From 4898db80cb7539a06e234c65aaaac85883209e38 Mon Sep 17 00:00:00 2001 From: rish9101 Date: Mon, 20 Jul 2020 01:12:28 +0530 Subject: Add post-process functionality in write_with_gap --- src/afl-fuzz-run.c | 61 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 2a1664e2..f8317863 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -142,18 +142,58 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at, s32 fd = afl->fsrv.out_fd; u32 tail_len = len - skip_at - skip_len; + /* We first copy the mem into a new memory region removing the gaps + and then carry out any post-processing work on them. Then copy them out to + shared-mem or write to file */ + + void *mem_trimmed = + ck_alloc(skip_at + tail_len + + 1); // 1 extra size allocated to remove chance of overflow + + if (skip_at) { memcpy(mem_trimmed, mem, skip_at); } + + if (tail_len) { + + memcpy(mem_trimmed + skip_at, (u8 *)mem + skip_at + skip_len, tail_len); + + } + + ssize_t new_size = skip_at + tail_len; + void * new_mem = mem_trimmed; + u8 * new_buf = NULL; + + if (unlikely(afl->custom_mutators_count)) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->afl_custom_post_process) { + + new_size = + el->afl_custom_post_process(el->data, new_mem, new_size, &new_buf); + + } + + new_mem = new_buf; + + }); + + } + if (afl->fsrv.shmem_fuzz) { - if (skip_at) { memcpy(afl->fsrv.shmem_fuzz, mem, skip_at); } + if ((new_buf)) { + + memcpy(afl->fsrv.shmem_fuzz, new_buf, new_size); + + } - if (tail_len) { + else { - memcpy(afl->fsrv.shmem_fuzz + skip_at, (u8 *)mem + skip_at + skip_len, - tail_len); + memcpy(afl->fsrv.shmem_fuzz, mem_trimmed, new_size); } - *afl->fsrv.shmem_fuzz_len = len - skip_len; + *afl->fsrv.shmem_fuzz_len = new_size; #ifdef _DEBUG if (afl->debug) { @@ -197,18 +237,19 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at, } - if (skip_at) { ck_write(fd, mem, skip_at, afl->fsrv.out_file); } + if (new_buf) { - u8 *memu8 = mem; - if (tail_len) { + ck_write(fd, new_buf, new_size, afl->fsrv.out_file); + + } else { - ck_write(fd, memu8 + skip_at + skip_len, tail_len, afl->fsrv.out_file); + ck_write(fd, mem_trimmed, new_size, afl->fsrv.out_file); } if (!afl->fsrv.out_file) { - if (ftruncate(fd, len - skip_len)) { PFATAL("ftruncate() failed"); } + if (ftruncate(fd, new_size)) { PFATAL("ftruncate() failed"); } lseek(fd, 0, SEEK_SET); } else { -- cgit v1.2.3 From 2fa31dab60e76ee1a4b77d2d98d58e0e35455880 Mon Sep 17 00:00:00 2001 From: rish9101 Date: Thu, 23 Jul 2020 23:48:26 +0530 Subject: Remove reduntant copying from write_with_gap function --- src/afl-fuzz-run.c | 66 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index f8317863..7d68083d 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -142,35 +142,55 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at, s32 fd = afl->fsrv.out_fd; u32 tail_len = len - skip_at - skip_len; - /* We first copy the mem into a new memory region removing the gaps - and then carry out any post-processing work on them. Then copy them out to - shared-mem or write to file */ - - void *mem_trimmed = - ck_alloc(skip_at + tail_len + - 1); // 1 extra size allocated to remove chance of overflow - - if (skip_at) { memcpy(mem_trimmed, mem, skip_at); } - - if (tail_len) { - - memcpy(mem_trimmed + skip_at, (u8 *)mem + skip_at + skip_len, tail_len); - - } + /* + This memory is used to carry out the post_processing(if present) after copying + the testcase by removing the gaps + */ + u8 mem_trimmed[skip_at + tail_len + + 1]; // 1 extra size to remove chance of overflow ssize_t new_size = skip_at + tail_len; - void * new_mem = mem_trimmed; + void * new_mem = mem; u8 * new_buf = NULL; + bool post_process_skipped = true; + if (unlikely(afl->custom_mutators_count)) { + new_mem = mem_trimmed; + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { if (el->afl_custom_post_process) { + // We copy into the mem_trimmed only if we actually have custom mutators + // *with* post_processing installed + + if (post_process_skipped) { + + if (skip_at) { memcpy(mem_trimmed, (u8 *)mem, skip_at); } + + if (tail_len) { + + memcpy(mem_trimmed + skip_at, (u8 *)mem + skip_at + skip_len, + tail_len); + + } + + post_process_skipped = false; + + } + new_size = el->afl_custom_post_process(el->data, new_mem, new_size, &new_buf); + if (unlikely(!new_buf && (new_size <= 0))) { + + FATAL("Custom_post_process failed (ret: %lu)", + (long unsigned)new_size); + + } + } new_mem = new_buf; @@ -181,7 +201,9 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at, if (afl->fsrv.shmem_fuzz) { - if ((new_buf)) { + if (!post_process_skipped) { + + // If we did post_processing, copy directly from the new_buf bufer memcpy(afl->fsrv.shmem_fuzz, new_buf, new_size); @@ -189,7 +211,9 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at, else { - memcpy(afl->fsrv.shmem_fuzz, mem_trimmed, new_size); + memcpy(afl->fsrv.shmem_fuzz, mem, skip_at); + + memcpy(afl->fsrv.shmem_fuzz, mem + skip_at + skip_len, tail_len); } @@ -237,13 +261,15 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at, } - if (new_buf) { + if (!post_process_skipped) { ck_write(fd, new_buf, new_size, afl->fsrv.out_file); } else { - ck_write(fd, mem_trimmed, new_size, afl->fsrv.out_file); + ck_write(fd, mem, skip_at, afl->fsrv.out_file); + + ck_write(fd, mem + skip_at + skip_len, tail_len, afl->fsrv.out_file); } -- cgit v1.2.3 From 565da10a8f46e9910ac5edecb1c5e68ee8c66b0d Mon Sep 17 00:00:00 2001 From: Rishi Ranjan Date: Wed, 29 Jul 2020 01:05:05 +0530 Subject: Minor change to write_with_gap --- src/afl-fuzz-run.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 7d68083d..e4ddab1b 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -144,12 +144,12 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at, /* This memory is used to carry out the post_processing(if present) after copying - the testcase by removing the gaps + the testcase by removing the gaps. This can break though */ - u8 mem_trimmed[skip_at + tail_len + + u8 mem_trimmed[len - skip_len + 1]; // 1 extra size to remove chance of overflow - ssize_t new_size = skip_at + tail_len; + ssize_t new_size = len - skip_len; void * new_mem = mem; u8 * new_buf = NULL; -- cgit v1.2.3 From 35a448ee921158c586177ff8fe0cd82da4345f68 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 30 Jul 2020 09:20:22 +0200 Subject: enhance for custom trim buffer --- src/afl-fuzz-run.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 01963f8f..691d32f8 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -134,6 +134,8 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { } +#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size + /* The same, but with an adjustable gap. Used for trimming. */ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at, @@ -146,8 +148,7 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at, This memory is used to carry out the post_processing(if present) after copying the testcase by removing the gaps. This can break though */ - u8 mem_trimmed[len - skip_len + - 1]; // 1 extra size to remove chance of overflow + u8 *mem_trimmed = ck_maybe_grow(BUF_PARAMS(out_scratch), len - skip_len + 1); ssize_t new_size = len - skip_len; void * new_mem = mem; @@ -286,6 +287,8 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at, } +#undef BUF_PARAMS + /* Calibrate a new test case. This is done when processing the input directory to warn about flaky or otherwise problematic test cases early on; and when new paths are discovered to detect variable behavior and so on. */ -- cgit v1.2.3 From fc401f1acc61b73f328a16ac10bed268134c495e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 30 Jul 2020 11:51:13 +0200 Subject: fix post process check --- src/afl-fuzz-run.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 691d32f8..44d3c522 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -185,7 +185,7 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at, new_size = el->afl_custom_post_process(el->data, new_mem, new_size, &new_buf); - if (unlikely(!new_buf && (new_size <= 0))) { + if (unlikely(!new_buf || (new_size <= 0))) { FATAL("Custom_post_process failed (ret: %lu)", (long unsigned)new_size); -- cgit v1.2.3 From ea9ba53cdbc6d175f3f055c9a308668ebaacda1e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 30 Jul 2020 17:09:22 +0200 Subject: fix oob reads, code-format --- src/afl-fuzz-queue.c | 55 ++++++++++++++++++++++++++----------------------- src/afl-fuzz-redqueen.c | 3 +-- 2 files changed, 30 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 38e95ac8..71874283 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -139,7 +139,8 @@ static u8 check_if_text(struct queue_entry *q) { // non-overlong 2-byte if (((0xC2 <= buf[offset + 0] && buf[offset + 0] <= 0xDF) && - (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF))) { + (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF)) && + len - offset > 1) { offset += 2; utf8++; @@ -149,18 +150,19 @@ static u8 check_if_text(struct queue_entry *q) { } // excluding overlongs - if ((buf[offset + 0] == 0xE0 && - (0xA0 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && - (0x80 <= buf[offset + 2] && - buf[offset + 2] <= 0xBF)) || // straight 3-byte - (((0xE1 <= buf[offset + 0] && buf[offset + 0] <= 0xEC) || - buf[offset + 0] == 0xEE || buf[offset + 0] == 0xEF) && - (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && - (0x80 <= buf[offset + 2] && - buf[offset + 2] <= 0xBF)) || // excluding surrogates - (buf[offset + 0] == 0xED && - (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0x9F) && - (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF))) { + if ((len - offset > 2) && + ((buf[offset + 0] == 0xE0 && + (0xA0 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && + (0x80 <= buf[offset + 2] && + buf[offset + 2] <= 0xBF)) || // straight 3-byte + (((0xE1 <= buf[offset + 0] && buf[offset + 0] <= 0xEC) || + buf[offset + 0] == 0xEE || buf[offset + 0] == 0xEF) && + (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && + (0x80 <= buf[offset + 2] && + buf[offset + 2] <= 0xBF)) || // excluding surrogates + (buf[offset + 0] == 0xED && + (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0x9F) && + (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF)))) { offset += 3; utf8++; @@ -170,19 +172,20 @@ static u8 check_if_text(struct queue_entry *q) { } // planes 1-3 - if ((buf[offset + 0] == 0xF0 && - (0x90 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && - (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) && - (0x80 <= buf[offset + 3] && - buf[offset + 3] <= 0xBF)) || // planes 4-15 - ((0xF1 <= buf[offset + 0] && buf[offset + 0] <= 0xF3) && - (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && - (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) && - (0x80 <= buf[offset + 3] && buf[offset + 3] <= 0xBF)) || // plane 16 - (buf[offset + 0] == 0xF4 && - (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0x8F) && - (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) && - (0x80 <= buf[offset + 3] && buf[offset + 3] <= 0xBF))) { + if ((len - offset > 3) && + ((buf[offset + 0] == 0xF0 && + (0x90 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && + (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) && + (0x80 <= buf[offset + 3] && + buf[offset + 3] <= 0xBF)) || // planes 4-15 + ((0xF1 <= buf[offset + 0] && buf[offset + 0] <= 0xF3) && + (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) && + (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) && + (0x80 <= buf[offset + 3] && buf[offset + 3] <= 0xBF)) || // plane 16 + (buf[offset + 0] == 0xF4 && + (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0x8F) && + (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) && + (0x80 <= buf[offset + 3] && buf[offset + 3] <= 0xBF)))) { offset += 4; utf8++; diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 57e60c3d..a2e8f992 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -269,8 +269,7 @@ static long long strntoll(const char *str, size_t sz, char **end, int base) { long long ret; const char *beg = str; - for (; beg && sz && *beg == ' '; beg++, sz--) - ; + for (; beg && sz && *beg == ' '; beg++, sz--) {}; if (!sz || sz >= sizeof(buf)) { -- cgit v1.2.3 From 8e809d8593d9230c123aa22c8cd0b695e54d7c68 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 30 Jul 2020 17:51:32 +0200 Subject: added NULL check --- src/afl-common.c | 6 ++++-- src/afl-fuzz-redqueen.c | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index c023789b..367dec72 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -145,7 +145,8 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { char **new_argv = ck_alloc(sizeof(char *) * (argc + 4)); u8 * tmp, *cp = NULL, *rsl, *own_copy; - memcpy(new_argv + 3, argv + 1, (int)(sizeof(char *)) * argc); + memcpy(&new_argv[3], &argv[1], (int)(sizeof(char *)) * (argc - 1)); + new_argv[argc - 1] = NULL; new_argv[2] = *target_path_p; new_argv[1] = "--"; @@ -226,7 +227,8 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { char **new_argv = ck_alloc(sizeof(char *) * (argc + 3)); u8 * tmp, *cp = NULL, *rsl, *own_copy; - memcpy(new_argv + 2, argv + 1, (int)(sizeof(char *)) * argc); + memcpy(&new_argv[2], &argv[1], (int)(sizeof(char *)) * (argc - 1)); + new_argv[argc - 1] = NULL; new_argv[1] = *target_path_p; diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index a2e8f992..d86190a6 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -319,6 +319,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u8 *orig_buf, u8 *buf, u32 len, u8 do_reverse, u8 *status) { + if (!buf) { FATAL("BUG: buf was NULL. Please report this.\n"); } + u64 *buf_64 = (u64 *)&buf[idx]; u32 *buf_32 = (u32 *)&buf[idx]; u16 *buf_16 = (u16 *)&buf[idx]; -- cgit v1.2.3 From 320f26d26f7e0cbe093e6f5af5f27f180bc31a1b Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 30 Jul 2020 19:00:41 +0200 Subject: add -b option to afl-fuzz --- src/afl-fuzz-init.c | 22 +++++++++++++++++----- src/afl-fuzz-state.c | 1 + src/afl-fuzz.c | 19 ++++++++++++++++--- 3 files changed, 34 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 65ad0c9f..ad92dff6 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -53,6 +53,13 @@ void bind_to_free_cpu(afl_state_t *afl) { u8 cpu_used[4096] = {0}, lockfile[PATH_MAX] = ""; u32 i; + if (afl->cpu_to_bind != -1) { + + i = afl->cpu_to_bind; + goto set_cpu; + + } + if (afl->sync_id) { s32 lockfd, first = 1; @@ -295,20 +302,23 @@ void bind_to_free_cpu(afl_state_t *afl) { try: + if (afl->cpu_to_bind != -1) + FATAL("bind to CPU #%d failed!", afl->cpu_to_bind); + #if !defined(__ANDROID__) - for (i = cpu_start; i < afl->cpu_core_count; i++) { + for (i = cpu_start; i < afl->cpu_core_count; i++) { - if (!cpu_used[i]) { break; } + if (!cpu_used[i]) { break; } - } + } if (i == afl->cpu_core_count) { #else - for (i = afl->cpu_core_count - cpu_start - 1; i > -1; i--) - if (!cpu_used[i]) break; + for (i = afl->cpu_core_count - cpu_start - 1; i > -1; i--) + if (!cpu_used[i]) break; if (i == -1) { #endif @@ -327,6 +337,8 @@ void bind_to_free_cpu(afl_state_t *afl) { OKF("Found a free CPU core, try binding to #%u.", i); +set_cpu: + afl->cpu_aff = i; #if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 66280ed1..e2d62bc6 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -94,6 +94,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->havoc_div = 1; /* Cycle count divisor for havoc */ afl->stage_name = "init"; /* Name of the current fuzz stage */ afl->splicing_with = -1; /* Splicing with which test case? */ + afl->cpu_to_bind = -1; #ifdef HAVE_AFFINITY afl->cpu_aff = -1; /* Selected CPU core */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 5bedf6e1..e33a4bbd 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -143,6 +143,8 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) { //" -B bitmap.txt - mutate a specific test case, use the out/fuzz_bitmap //" "file\n" " -C - crash exploration mode (the peruvian rabbit thing)\n" + " -b cpu_id - bind the fuzzing process to the specified CPU core " + "(0-...)\n" " -e ext - file extension for the fuzz test input file (if " "needed)\n\n", argv0, EXEC_TIMEOUT, MEM_LIMIT, FOREIGN_SYNCS_MAX); @@ -271,9 +273,9 @@ int main(int argc, char **argv_orig, char **envp) { afl->shmem_testcase_mode = 1; // we always try to perform shmem fuzzing - while ((opt = getopt(argc, argv, - "+c:i:I:o:f:F:m:t:T:dDnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:")) > - 0) { + while ((opt = getopt( + argc, argv, + "+b:c:i:I:o:f:F:m:t:T:dDnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:")) > 0) { switch (opt) { @@ -281,6 +283,17 @@ int main(int argc, char **argv_orig, char **envp) { afl->infoexec = optarg; break; + case 'b': { /* bind CPU core */ + + if (afl->cpu_to_bind != -1) FATAL("Multiple -b options not supported"); + + if (sscanf(optarg, "%u", &afl->cpu_to_bind) < 0 || optarg[0] == '-') + FATAL("Bad syntax used for -b"); + + break; + + } + case 'c': { afl->shm.cmplog_mode = 1; -- cgit v1.2.3 From cd576fa59d1b413433beef1009668f4d9b22c965 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 31 Jul 2020 10:42:43 +0200 Subject: fixes --- src/afl-fuzz.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e33a4bbd..54db1efb 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -163,11 +163,13 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) { "AFL_BENCH_UNTIL_CRASH: exit soon when the first crashing input has been found\n" "AFL_CUSTOM_MUTATOR_LIBRARY: lib with afl_custom_fuzz() to mutate inputs\n" "AFL_CUSTOM_MUTATOR_ONLY: avoid AFL++'s internal mutators\n" + "AFL_CYCLE_SCHEDULES: after completing a cycle, switch to a different -p schedule\n" "AFL_DEBUG: extra debugging output for Python mode trimming\n" "AFL_DEBUG_CHILD_OUTPUT: do not suppress stdout/stderr from target\n" "AFL_DISABLE_TRIM: disable the trimming of test cases\n" "AFL_DUMB_FORKSRV: use fork server without feedback from target\n" "AFL_EXIT_WHEN_DONE: exit when all inputs are run and no new finds are found\n" + "AFL_EXPAND_HAVOC_NOW: immediately enable expand havoc mode (default: after 60 minutes and a cycle without finds)\n" "AFL_FAST_CAL: limit the calibration stage to three cycles for speedup\n" "AFL_FORCE_UI: force showing the status screen (for virtual consoles)\n" "AFL_HANG_TMOUT: override timeout value (in milliseconds)\n" -- cgit v1.2.3 From 630d2a934b2b7a9978452fb79aa36b51e0cce315 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 31 Jul 2020 14:36:58 +0200 Subject: less gotos --- src/afl-fuzz-mutators.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index b288cf9f..b30106a0 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -308,20 +308,23 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, unsuccessful trimming and skip it, instead of aborting the trimming. */ ++afl->trim_execs; - goto unsuccessful_trimming; } - write_to_testcase(afl, retbuf, retlen); + if (likely(retlen)) { - fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); - ++afl->trim_execs; + write_to_testcase(afl, retbuf, retlen); - if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; } + fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); + ++afl->trim_execs; + + if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; } - cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); + cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); - if (cksum == q->exec_cksum) { + } + + if (likely(retlen && cksum == q->exec_cksum)) { q->len = retlen; memcpy(in_buf, retbuf, retlen); @@ -349,8 +352,6 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, } else { - unsuccessful_trimming: - /* Tell the custom mutator that the trimming was unsuccessful */ afl->stage_cur = mutator->afl_custom_post_trim(mutator->data, 0); if (unlikely(afl->stage_cur < 0)) { -- cgit v1.2.3 From 729445b64f8156560ce1158a582d9528b0a39bf9 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 31 Jul 2020 18:17:03 +0200 Subject: Bind cpu (#480) * silence compiletime warning * refactored cpu binding * formatted code --- src/afl-fuzz-init.c | 223 ++++++++++++++++++++++++++-------------------------- 1 file changed, 110 insertions(+), 113 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index ad92dff6..1e4f8dee 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -28,10 +28,9 @@ #ifdef HAVE_AFFINITY -/* Build a list of processes bound to specific cores. Returns -1 if nothing - can be found. Assumes an upper bound of 4k CPUs. */ +/* bind process to a specific cpu. Returns 0 on failure. */ -void bind_to_free_cpu(afl_state_t *afl) { +static u8 bind_cpu(afl_state_t *afl, s32 cpuid) { #if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) cpu_set_t c; @@ -41,25 +40,108 @@ void bind_to_free_cpu(afl_state_t *afl) { psetid_t c; #endif - if (afl->cpu_core_count < 2) { return; } + afl->cpu_aff = cpuid; + + #if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) + + CPU_ZERO(&c); + CPU_SET(cpuid, &c); + + #elif defined(__NetBSD__) + + c = cpuset_create(); + if (c == NULL) { PFATAL("cpuset_create failed"); } + cpuset_set(cpuid, c); + + #elif defined(__sun) + + pset_create(&c); + if (pset_assign(c, cpuid, NULL)) { PFATAL("pset_assign failed"); } + + #endif + + #if defined(__linux__) + + return (sched_setaffinity(0, sizeof(c), &c) == 0); + + #elif defined(__FreeBSD__) || defined(__DragonFly__) + + return (pthread_setaffinity_np(pthread_self(), sizeof(c), &c) == 0); + + #elif defined(__NetBSD__) + + if (pthread_setaffinity_np(pthread_self(), cpuset_size(c), c)) { + + cpuset_destroy(c); + return 0; + + } + + cpuset_destroy(c); + return 1; + + #elif defined(__sun) + + if (pset_bind(c, P_PID, getpid(), NULL)) { + + pset_destroy(c); + return 0; + + } + + pset_destroy(c); + return 1; + + #else + + // this will need something for other platforms + // TODO: Solaris/Illumos has processor_bind ... might worth a try + WARNF("Cannot bind to CPU yet on this platform."); + return 1; + + #endif + +} + +/* Build a list of processes bound to specific cores. Returns -1 if nothing + can be found. Assumes an upper bound of 4k CPUs. */ + +void bind_to_free_cpu(afl_state_t *afl) { + + u8 cpu_used[4096] = {0}; + u8 lockfile[PATH_MAX] = ""; + u32 i; if (afl->afl_env.afl_no_affinity) { + if (afl->cpu_to_bind != -1) { + + FATAL("-b and AFL_NO_AFFINITY are mututally exclusive."); + + } + WARNF("Not binding to a CPU core (AFL_NO_AFFINITY set)."); return; } - u8 cpu_used[4096] = {0}, lockfile[PATH_MAX] = ""; - u32 i; - if (afl->cpu_to_bind != -1) { - i = afl->cpu_to_bind; - goto set_cpu; + if (!bind_cpu(afl, afl->cpu_to_bind)) { + + FATAL( + "Could not bind to requested CPU %d! Make sure you passed a valid " + "-b.", + afl->cpu_to_bind); + + } + + return; } + if (afl->cpu_core_count < 2) { return; } + if (afl->sync_id) { s32 lockfd, first = 1; @@ -300,135 +382,50 @@ void bind_to_free_cpu(afl_state_t *afl) { size_t cpu_start = 0; - try: - - if (afl->cpu_to_bind != -1) - FATAL("bind to CPU #%d failed!", afl->cpu_to_bind); - #if !defined(__ANDROID__) for (i = cpu_start; i < afl->cpu_core_count; i++) { - if (!cpu_used[i]) { break; } - - } - - if (i == afl->cpu_core_count) { - #else - for (i = afl->cpu_core_count - cpu_start - 1; i > -1; i--) - if (!cpu_used[i]) break; - if (i == -1) { - - #endif - - SAYF("\n" cLRD "[-] " cRST - "Uh-oh, looks like all %d CPU cores on your system are allocated to\n" - " other instances of afl-fuzz (or similar CPU-locked tasks). " - "Starting\n" - " another fuzzer on this machine is probably a bad plan, but if " - "you are\n" - " absolutely sure, you can set AFL_NO_AFFINITY and try again.\n", - afl->cpu_core_count); - FATAL("No more free CPU cores"); - - } - - OKF("Found a free CPU core, try binding to #%u.", i); - -set_cpu: + /* for some reason Android goes backwards */ - afl->cpu_aff = i; - - #if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) - - CPU_ZERO(&c); - CPU_SET(i, &c); - - #elif defined(__NetBSD__) - - c = cpuset_create(); - if (c == NULL) PFATAL("cpuset_create failed"); - cpuset_set(i, c); - - #elif defined(__sun) - -pset_create(&c); -if (pset_assign(c, i, NULL)) PFATAL("pset_assign failed"); + for (i = afl->cpu_core_count - 1; i > -1; i--) { #endif - #if defined(__linux__) + if (!cpu_used[i]) { continue; } - if (sched_setaffinity(0, sizeof(c), &c)) { + OKF("Found a free CPU core, try binding to #%u.", i); - if (cpu_start == afl->cpu_core_count) { + if (bind_cpu(afl, i)) { - PFATAL("sched_setaffinity failed for CPU %d, exit", i); + /* Success :) */ + break; } - WARNF("sched_setaffinity failed to CPU %d, trying next CPU", i); + WARNF("setaffinity failed to CPU %d, trying next CPU", i); cpu_start++; - goto try - ; } - #elif defined(__FreeBSD__) || defined(__DragonFly__) + if (lockfile[0]) unlink(lockfile); - if (pthread_setaffinity_np(pthread_self(), sizeof(c), &c)) { + if (i == afl->cpu_core_count || i == -1) { - if (cpu_start == afl->cpu_core_count) - PFATAL("pthread_setaffinity failed for cpu %d, exit", i); - WARNF("pthread_setaffinity failed to CPU %d, trying next CPU", i); - cpu_start++; - goto try - ; + SAYF("\n" cLRD "[-] " cRST + "Uh-oh, looks like all %d CPU cores on your system are allocated to\n" + " other instances of afl-fuzz (or similar CPU-locked tasks). " + "Starting\n" + " another fuzzer on this machine is probably a bad plan, but if " + "you are\n" + " absolutely sure, you can set AFL_NO_AFFINITY and try again.\n", + afl->cpu_core_count); + FATAL("No more free CPU cores"); } - #elif defined(__NetBSD__) - -if (pthread_setaffinity_np(pthread_self(), cpuset_size(c), c)) { - - if (cpu_start == afl->cpu_core_count) - PFATAL("pthread_setaffinity failed for cpu %d, exit", i); - WARNF("pthread_setaffinity failed to CPU %d, trying next CPU", i); - cpu_start++; - goto try - ; - -} - -cpuset_destroy(c); - - #elif defined(__sun) - -if (pset_bind(c, P_PID, getpid(), NULL)) { - - if (cpu_start == afl->cpu_core_count) - PFATAL("pset_bind failed for cpu %d, exit", i); - WARNF("pset_bind failed to CPU %d, trying next CPU", i); - cpu_start++; - goto try - ; - -} - -pset_destroy(c); - - #else - - // this will need something for other platforms - // TODO: Solaris/Illumos has processor_bind ... might worth a try - - #endif - - if (lockfile[0]) unlink(lockfile); - // we leave the environment variable to ensure a cleanup for other processes - } #endif /* HAVE_AFFINITY */ -- cgit v1.2.3 From 16b674c6523e151368443948b27c5e4aa6a3c7ee Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 31 Jul 2020 18:35:43 +0200 Subject: fix find free cpu --- src/afl-fuzz-init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 1e4f8dee..396a20f0 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -394,7 +394,7 @@ void bind_to_free_cpu(afl_state_t *afl) { #endif - if (!cpu_used[i]) { continue; } + if (cpu_used[i]) { continue; } OKF("Found a free CPU core, try binding to #%u.", i); -- cgit v1.2.3 From 54d96685808bd7b47de30f5028727d94b5369962 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 31 Jul 2020 17:21:17 +0000 Subject: Haiku set explicitly to performance. No command line to set through afl-system-config (the only one is a GUI). --- src/afl-fuzz.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 54db1efb..326ccc1c 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1057,6 +1057,11 @@ int main(int argc, char **argv_orig, char **envp) { bind_to_free_cpu(afl); #endif /* HAVE_AFFINITY */ + #ifdef __HAIKU__ + /* Prioritizes performance over power saving */ + set_scheduler_mode(SCHEDULER_MODE_LOW_LATENCY); + #endif + afl->fsrv.trace_bits = afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode); -- cgit v1.2.3 From 491cee669f858bfea2b0db2fe540200b0f2625e6 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Mon, 3 Aug 2020 11:15:12 +0200 Subject: fix #483 --- src/afl-fuzz-redqueen.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index d86190a6..b58c8537 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -673,14 +673,15 @@ static u8 rtn_extend_encoding(afl_state_t *afl, struct cmp_header *h, for (i = 0; i < its_len; ++i) { - if (pattern[idx + i] != buf[idx + i] || - o_pattern[idx + i] != orig_buf[idx + i] || *status == 1) { + if (pattern[i] != buf[idx + i] || + o_pattern[i] != orig_buf[idx + i] || *status == 1) { break; } - buf[idx + i] = repl[idx + i]; + buf[idx + i] = repl[i]; + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } } @@ -726,7 +727,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { } for (idx = 0; idx < len && fails < 8; ++idx) { - + if (unlikely(rtn_extend_encoding(afl, h, o->v0, o->v1, orig_o->v0, idx, orig_buf, buf, len, &status))) { -- cgit v1.2.3 From 409e4ae945ab5aeb31b1e3a1497ce5fc65226f07 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 3 Aug 2020 13:13:32 +0200 Subject: fix expand havoc for ..._only modes --- src/afl-fuzz-redqueen.c | 8 ++++---- src/afl-fuzz.c | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index b58c8537..cb4c78df 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -673,15 +673,15 @@ static u8 rtn_extend_encoding(afl_state_t *afl, struct cmp_header *h, for (i = 0; i < its_len; ++i) { - if (pattern[i] != buf[idx + i] || - o_pattern[i] != orig_buf[idx + i] || *status == 1) { + if (pattern[i] != buf[idx + i] || o_pattern[i] != orig_buf[idx + i] || + *status == 1) { break; } buf[idx + i] = repl[i]; - + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } } @@ -727,7 +727,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { } for (idx = 0; idx < len && fails < 8; ++idx) { - + if (unlikely(rtn_extend_encoding(afl, h, o->v0, o->v1, orig_o->v0, idx, orig_buf, buf, len, &status))) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 326ccc1c..da30797c 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1304,7 +1304,8 @@ int main(int argc, char **argv_orig, char **envp) { afl->expand_havoc = 1; break; case 1: - if (afl->limit_time_sig == 0) { + if (afl->limit_time_sig == 0 && !afl->custom_only && + !afl->python_only) { afl->limit_time_sig = -1; afl->limit_time_puppet = 0; -- cgit v1.2.3 From 38bed607d1f52ad7ede7792fe01163358a703953 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 3 Aug 2020 20:50:47 +0200 Subject: code format --- src/afl-fuzz-init.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 396a20f0..2c17ffbb 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -490,9 +490,13 @@ void read_foreign_testcases(afl_state_t *afl, int first) { if (nl_cnt == 0) { - if (first) + if (first) { + WARNF("directory %s is currently empty", afl->foreign_syncs[iter].dir); + + } + continue; } @@ -540,11 +544,15 @@ void read_foreign_testcases(afl_state_t *afl, int first) { if (st.st_size > MAX_FILE) { - if (first) + if (first) { + WARNF( "Test case '%s' is too big (%s, limit is %s), skipping", fn2, stringify_mem_size(val_buf[0], sizeof(val_buf[0]), st.st_size), stringify_mem_size(val_buf[1], sizeof(val_buf[1]), MAX_FILE)); + + } + ck_free(fn2); continue; -- cgit v1.2.3 From c8354d751606e0f7a0364685958036bb7031e35a Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 4 Aug 2020 23:22:42 +0200 Subject: new rand mode for data offsets that prefer low offset values --- src/afl-fuzz-one.c | 73 +++++++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 1f0bf30e..77bce7d0 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1921,14 +1921,14 @@ havoc_stage: /* Flip a single bit somewhere. Spooky! */ - FLIP_BIT(out_buf, rand_below(afl, temp_len << 3)); + FLIP_BIT(out_buf, rand_below_datalen(afl, temp_len << 3)); break; case 1: /* Set byte to interesting value. */ - out_buf[rand_below(afl, temp_len)] = + out_buf[rand_below_datalen(afl, temp_len)] = interesting_8[rand_below(afl, sizeof(interesting_8))]; break; @@ -1940,12 +1940,12 @@ havoc_stage: if (rand_below(afl, 2)) { - *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = + *(u16 *)(out_buf + rand_below_datalen(afl, temp_len - 1)) = interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]; } else { - *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = SWAP16( + *(u16 *)(out_buf + rand_below_datalen(afl, temp_len - 1)) = SWAP16( interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]); } @@ -1960,12 +1960,12 @@ havoc_stage: if (rand_below(afl, 2)) { - *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = + *(u32 *)(out_buf + rand_below_datalen(afl, temp_len - 3)) = interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]; } else { - *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = SWAP32( + *(u32 *)(out_buf + rand_below_datalen(afl, temp_len - 3)) = SWAP32( interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]); } @@ -1976,14 +1976,16 @@ havoc_stage: /* Randomly subtract from byte. */ - out_buf[rand_below(afl, temp_len)] -= 1 + rand_below(afl, ARITH_MAX); + out_buf[rand_below_datalen(afl, temp_len)] -= + 1 + rand_below(afl, ARITH_MAX); break; case 5: /* Randomly add to byte. */ - out_buf[rand_below(afl, temp_len)] += 1 + rand_below(afl, ARITH_MAX); + out_buf[rand_below_datalen(afl, temp_len)] += + 1 + rand_below(afl, ARITH_MAX); break; case 6: @@ -1994,13 +1996,13 @@ havoc_stage: if (rand_below(afl, 2)) { - u32 pos = rand_below(afl, temp_len - 1); + u32 pos = rand_below_datalen(afl, temp_len - 1); *(u16 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); } else { - u32 pos = rand_below(afl, temp_len - 1); + u32 pos = rand_below_datalen(afl, temp_len - 1); u16 num = 1 + rand_below(afl, ARITH_MAX); *(u16 *)(out_buf + pos) = @@ -2018,13 +2020,13 @@ havoc_stage: if (rand_below(afl, 2)) { - u32 pos = rand_below(afl, temp_len - 1); + u32 pos = rand_below_datalen(afl, temp_len - 1); *(u16 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); } else { - u32 pos = rand_below(afl, temp_len - 1); + u32 pos = rand_below_datalen(afl, temp_len - 1); u16 num = 1 + rand_below(afl, ARITH_MAX); *(u16 *)(out_buf + pos) = @@ -2042,13 +2044,13 @@ havoc_stage: if (rand_below(afl, 2)) { - u32 pos = rand_below(afl, temp_len - 3); + u32 pos = rand_below_datalen(afl, temp_len - 3); *(u32 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); } else { - u32 pos = rand_below(afl, temp_len - 3); + u32 pos = rand_below_datalen(afl, temp_len - 3); u32 num = 1 + rand_below(afl, ARITH_MAX); *(u32 *)(out_buf + pos) = @@ -2066,13 +2068,13 @@ havoc_stage: if (rand_below(afl, 2)) { - u32 pos = rand_below(afl, temp_len - 3); + u32 pos = rand_below_datalen(afl, temp_len - 3); *(u32 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); } else { - u32 pos = rand_below(afl, temp_len - 3); + u32 pos = rand_below_datalen(afl, temp_len - 3); u32 num = 1 + rand_below(afl, ARITH_MAX); *(u32 *)(out_buf + pos) = @@ -2088,7 +2090,8 @@ havoc_stage: why not. We use XOR with 1-255 to eliminate the possibility of a no-op. */ - out_buf[rand_below(afl, temp_len)] ^= 1 + rand_below(afl, 255); + out_buf[rand_below_datalen(afl, temp_len)] ^= + 1 + rand_below(afl, 255); break; case 11 ... 12: { @@ -2105,7 +2108,7 @@ havoc_stage: del_len = choose_block_len(afl, temp_len - 1); - del_from = rand_below(afl, temp_len - del_len + 1); + del_from = rand_below_datalen(afl, temp_len - del_len + 1); memmove(out_buf + del_from, out_buf + del_from + del_len, temp_len - del_from - del_len); @@ -2129,7 +2132,7 @@ havoc_stage: if (actually_clone) { clone_len = choose_block_len(afl, temp_len); - clone_from = rand_below(afl, temp_len - clone_len + 1); + clone_from = rand_below_datalen(afl, temp_len - clone_len + 1); } else { @@ -2138,7 +2141,7 @@ havoc_stage: } - clone_to = rand_below(afl, temp_len); + clone_to = rand_below_datalen(afl, temp_len); new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); @@ -2156,8 +2159,9 @@ havoc_stage: } else { memset(new_buf + clone_to, - rand_below(afl, 2) ? rand_below(afl, 256) - : out_buf[rand_below(afl, temp_len)], + rand_below(afl, 2) + ? rand_below(afl, 256) + : out_buf[rand_below_datalen(afl, temp_len)], clone_len); } @@ -2186,8 +2190,8 @@ havoc_stage: copy_len = choose_block_len(afl, temp_len - 1); - copy_from = rand_below(afl, temp_len - copy_len + 1); - copy_to = rand_below(afl, temp_len - copy_len + 1); + copy_from = rand_below_datalen(afl, temp_len - copy_len + 1); + copy_to = rand_below_datalen(afl, temp_len - copy_len + 1); if (rand_below(afl, 4)) { @@ -2200,8 +2204,9 @@ havoc_stage: } else { memset(out_buf + copy_to, - rand_below(afl, 2) ? rand_below(afl, 256) - : out_buf[rand_below(afl, temp_len)], + rand_below(afl, 2) + ? rand_below(afl, 256) + : out_buf[rand_below_datalen(afl, temp_len)], copy_len); } @@ -2233,7 +2238,7 @@ havoc_stage: if (extra_len > temp_len) { break; } - insert_at = rand_below(afl, temp_len - extra_len + 1); + insert_at = rand_below_datalen(afl, temp_len - extra_len + 1); memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, extra_len); @@ -2247,7 +2252,7 @@ havoc_stage: if (extra_len > temp_len) { break; } - insert_at = rand_below(afl, temp_len - extra_len + 1); + insert_at = rand_below_datalen(afl, temp_len - extra_len + 1); memcpy(out_buf + insert_at, afl->extras[use_extra].data, extra_len); @@ -2258,7 +2263,7 @@ havoc_stage: } else { // case 16 u32 use_extra, extra_len, - insert_at = rand_below(afl, temp_len + 1); + insert_at = rand_below_datalen(afl, temp_len + 1); u8 *ptr; /* Insert an extra. Do the same dice-rolling stuff as for the @@ -2362,8 +2367,8 @@ havoc_stage: copy_len = choose_block_len(afl, new_len - 1); if (copy_len > temp_len) copy_len = temp_len; - copy_from = rand_below(afl, new_len - copy_len + 1); - copy_to = rand_below(afl, temp_len - copy_len + 1); + copy_from = rand_below_datalen(afl, new_len - copy_len + 1); + copy_to = rand_below_datalen(afl, temp_len - copy_len + 1); memmove(out_buf + copy_to, new_buf + copy_from, copy_len); @@ -2372,9 +2377,9 @@ havoc_stage: u32 clone_from, clone_to, clone_len; clone_len = choose_block_len(afl, new_len); - clone_from = rand_below(afl, new_len - clone_len + 1); + clone_from = rand_below_datalen(afl, new_len - clone_len + 1); - clone_to = rand_below(afl, temp_len); + clone_to = rand_below_datalen(afl, temp_len); u8 *temp_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); @@ -2523,7 +2528,7 @@ retry_splicing: /* Split somewhere between the first and last differing byte. */ - split_at = f_diff + rand_below(afl, l_diff - f_diff); + split_at = f_diff + rand_below_datalen(afl, l_diff - f_diff); /* Do the thing. */ -- cgit v1.2.3 From f30ca1476c2d4d08d46fe9657ad4aa1d828eb578 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 5 Aug 2020 11:17:15 +0200 Subject: fix short write --- src/afl-fuzz-queue.c | 2 ++ src/afl-fuzz-run.c | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 71874283..f35df914 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -112,8 +112,10 @@ static u8 check_if_text(struct queue_entry *q) { u8 buf[MAX_FILE]; s32 fd, len = q->len, offset = 0, ascii = 0, utf8 = 0, comp; + if (len >= MAX_FILE) len = MAX_FILE - 1; if ((fd = open(q->fname, O_RDONLY)) < 0) return 0; if ((comp = read(fd, buf, len)) != len) return 0; + buf[len] = 0; close(fd); while (offset < len) { diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 44d3c522..ed4a1081 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -819,16 +819,27 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { fd = open(q->fname, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fd < 0) { PFATAL("Unable to create '%s'", q->fname); } + + u32 written = 0; + while (written < q->len) { + + ssize_t result = write(fd, in_buf, q->len - written); + if (result > 0) written += result; + + } + } else { unlink(q->fname); /* ignore errors */ fd = open(q->fname, O_WRONLY | O_CREAT | O_EXCL, 0600); - } + if (fd < 0) { PFATAL("Unable to create '%s'", q->fname); } - if (fd < 0) { PFATAL("Unable to create '%s'", q->fname); } + ck_write(fd, in_buf, q->len, q->fname); + + } - ck_write(fd, in_buf, q->len, q->fname); close(fd); memcpy(afl->fsrv.trace_bits, afl->clean_trace, afl->fsrv.map_size); -- cgit v1.2.3 From e2434cf8c6db86e1e7b67cb3b73e417c2a7fd3bd Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 6 Aug 2020 23:27:50 +0200 Subject: remove datalen in havoc --- src/afl-fuzz-one.c | 73 +++++++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 77bce7d0..1f0bf30e 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1921,14 +1921,14 @@ havoc_stage: /* Flip a single bit somewhere. Spooky! */ - FLIP_BIT(out_buf, rand_below_datalen(afl, temp_len << 3)); + FLIP_BIT(out_buf, rand_below(afl, temp_len << 3)); break; case 1: /* Set byte to interesting value. */ - out_buf[rand_below_datalen(afl, temp_len)] = + out_buf[rand_below(afl, temp_len)] = interesting_8[rand_below(afl, sizeof(interesting_8))]; break; @@ -1940,12 +1940,12 @@ havoc_stage: if (rand_below(afl, 2)) { - *(u16 *)(out_buf + rand_below_datalen(afl, temp_len - 1)) = + *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]; } else { - *(u16 *)(out_buf + rand_below_datalen(afl, temp_len - 1)) = SWAP16( + *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = SWAP16( interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]); } @@ -1960,12 +1960,12 @@ havoc_stage: if (rand_below(afl, 2)) { - *(u32 *)(out_buf + rand_below_datalen(afl, temp_len - 3)) = + *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]; } else { - *(u32 *)(out_buf + rand_below_datalen(afl, temp_len - 3)) = SWAP32( + *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = SWAP32( interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]); } @@ -1976,16 +1976,14 @@ havoc_stage: /* Randomly subtract from byte. */ - out_buf[rand_below_datalen(afl, temp_len)] -= - 1 + rand_below(afl, ARITH_MAX); + out_buf[rand_below(afl, temp_len)] -= 1 + rand_below(afl, ARITH_MAX); break; case 5: /* Randomly add to byte. */ - out_buf[rand_below_datalen(afl, temp_len)] += - 1 + rand_below(afl, ARITH_MAX); + out_buf[rand_below(afl, temp_len)] += 1 + rand_below(afl, ARITH_MAX); break; case 6: @@ -1996,13 +1994,13 @@ havoc_stage: if (rand_below(afl, 2)) { - u32 pos = rand_below_datalen(afl, temp_len - 1); + u32 pos = rand_below(afl, temp_len - 1); *(u16 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); } else { - u32 pos = rand_below_datalen(afl, temp_len - 1); + u32 pos = rand_below(afl, temp_len - 1); u16 num = 1 + rand_below(afl, ARITH_MAX); *(u16 *)(out_buf + pos) = @@ -2020,13 +2018,13 @@ havoc_stage: if (rand_below(afl, 2)) { - u32 pos = rand_below_datalen(afl, temp_len - 1); + u32 pos = rand_below(afl, temp_len - 1); *(u16 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); } else { - u32 pos = rand_below_datalen(afl, temp_len - 1); + u32 pos = rand_below(afl, temp_len - 1); u16 num = 1 + rand_below(afl, ARITH_MAX); *(u16 *)(out_buf + pos) = @@ -2044,13 +2042,13 @@ havoc_stage: if (rand_below(afl, 2)) { - u32 pos = rand_below_datalen(afl, temp_len - 3); + u32 pos = rand_below(afl, temp_len - 3); *(u32 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); } else { - u32 pos = rand_below_datalen(afl, temp_len - 3); + u32 pos = rand_below(afl, temp_len - 3); u32 num = 1 + rand_below(afl, ARITH_MAX); *(u32 *)(out_buf + pos) = @@ -2068,13 +2066,13 @@ havoc_stage: if (rand_below(afl, 2)) { - u32 pos = rand_below_datalen(afl, temp_len - 3); + u32 pos = rand_below(afl, temp_len - 3); *(u32 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); } else { - u32 pos = rand_below_datalen(afl, temp_len - 3); + u32 pos = rand_below(afl, temp_len - 3); u32 num = 1 + rand_below(afl, ARITH_MAX); *(u32 *)(out_buf + pos) = @@ -2090,8 +2088,7 @@ havoc_stage: why not. We use XOR with 1-255 to eliminate the possibility of a no-op. */ - out_buf[rand_below_datalen(afl, temp_len)] ^= - 1 + rand_below(afl, 255); + out_buf[rand_below(afl, temp_len)] ^= 1 + rand_below(afl, 255); break; case 11 ... 12: { @@ -2108,7 +2105,7 @@ havoc_stage: del_len = choose_block_len(afl, temp_len - 1); - del_from = rand_below_datalen(afl, temp_len - del_len + 1); + del_from = rand_below(afl, temp_len - del_len + 1); memmove(out_buf + del_from, out_buf + del_from + del_len, temp_len - del_from - del_len); @@ -2132,7 +2129,7 @@ havoc_stage: if (actually_clone) { clone_len = choose_block_len(afl, temp_len); - clone_from = rand_below_datalen(afl, temp_len - clone_len + 1); + clone_from = rand_below(afl, temp_len - clone_len + 1); } else { @@ -2141,7 +2138,7 @@ havoc_stage: } - clone_to = rand_below_datalen(afl, temp_len); + clone_to = rand_below(afl, temp_len); new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); @@ -2159,9 +2156,8 @@ havoc_stage: } else { memset(new_buf + clone_to, - rand_below(afl, 2) - ? rand_below(afl, 256) - : out_buf[rand_below_datalen(afl, temp_len)], + rand_below(afl, 2) ? rand_below(afl, 256) + : out_buf[rand_below(afl, temp_len)], clone_len); } @@ -2190,8 +2186,8 @@ havoc_stage: copy_len = choose_block_len(afl, temp_len - 1); - copy_from = rand_below_datalen(afl, temp_len - copy_len + 1); - copy_to = rand_below_datalen(afl, temp_len - copy_len + 1); + copy_from = rand_below(afl, temp_len - copy_len + 1); + copy_to = rand_below(afl, temp_len - copy_len + 1); if (rand_below(afl, 4)) { @@ -2204,9 +2200,8 @@ havoc_stage: } else { memset(out_buf + copy_to, - rand_below(afl, 2) - ? rand_below(afl, 256) - : out_buf[rand_below_datalen(afl, temp_len)], + rand_below(afl, 2) ? rand_below(afl, 256) + : out_buf[rand_below(afl, temp_len)], copy_len); } @@ -2238,7 +2233,7 @@ havoc_stage: if (extra_len > temp_len) { break; } - insert_at = rand_below_datalen(afl, temp_len - extra_len + 1); + insert_at = rand_below(afl, temp_len - extra_len + 1); memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, extra_len); @@ -2252,7 +2247,7 @@ havoc_stage: if (extra_len > temp_len) { break; } - insert_at = rand_below_datalen(afl, temp_len - extra_len + 1); + insert_at = rand_below(afl, temp_len - extra_len + 1); memcpy(out_buf + insert_at, afl->extras[use_extra].data, extra_len); @@ -2263,7 +2258,7 @@ havoc_stage: } else { // case 16 u32 use_extra, extra_len, - insert_at = rand_below_datalen(afl, temp_len + 1); + insert_at = rand_below(afl, temp_len + 1); u8 *ptr; /* Insert an extra. Do the same dice-rolling stuff as for the @@ -2367,8 +2362,8 @@ havoc_stage: copy_len = choose_block_len(afl, new_len - 1); if (copy_len > temp_len) copy_len = temp_len; - copy_from = rand_below_datalen(afl, new_len - copy_len + 1); - copy_to = rand_below_datalen(afl, temp_len - copy_len + 1); + copy_from = rand_below(afl, new_len - copy_len + 1); + copy_to = rand_below(afl, temp_len - copy_len + 1); memmove(out_buf + copy_to, new_buf + copy_from, copy_len); @@ -2377,9 +2372,9 @@ havoc_stage: u32 clone_from, clone_to, clone_len; clone_len = choose_block_len(afl, new_len); - clone_from = rand_below_datalen(afl, new_len - clone_len + 1); + clone_from = rand_below(afl, new_len - clone_len + 1); - clone_to = rand_below_datalen(afl, temp_len); + clone_to = rand_below(afl, temp_len); u8 *temp_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); @@ -2528,7 +2523,7 @@ retry_splicing: /* Split somewhere between the first and last differing byte. */ - split_at = f_diff + rand_below_datalen(afl, l_diff - f_diff); + split_at = f_diff + rand_below(afl, l_diff - f_diff); /* Do the thing. */ -- cgit v1.2.3 From fb14e55cc960e03443c1c7b608287398a0cf0d3e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 7 Aug 2020 09:05:40 +0200 Subject: fix -N description --- src/afl-fuzz.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index da30797c..c73a76c6 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -115,8 +115,8 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) { " if using QEMU, just use -c 0.\n\n" "Fuzzing behavior settings:\n" - " -N - do not unlink the fuzzing input file (only for " - "devices etc.!)\n" + " -N - do not unlink the fuzzing input file (for devices " + "etc.)\n" " -d - quick & dirty mode (skips deterministic steps)\n" " -n - fuzz without instrumentation (non-instrumented mode)\n" " -x dict_file - optional fuzzer dictionary (see README.md, its really " -- cgit v1.2.3 From 22d3a5e90abd58c6a4bb68bf1b3f7ece8283f5bb Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 7 Aug 2020 16:55:58 +0200 Subject: enabled Wextra, fixed bugs --- src/afl-analyze.c | 5 ++- src/afl-as.c | 4 +- src/afl-forkserver.c | 6 ++- src/afl-fuzz-extras.c | 8 ++-- src/afl-fuzz-init.c | 11 ++++-- src/afl-fuzz-one.c | 99 ++++++++++++++++++++++++++----------------------- src/afl-fuzz-python.c | 7 ++++ src/afl-fuzz-redqueen.c | 14 +++---- src/afl-fuzz-run.c | 4 +- src/afl-fuzz-stats.c | 6 +-- src/afl-fuzz.c | 6 +-- src/afl-showmap.c | 6 +-- src/afl-tmin.c | 17 +++++---- 13 files changed, 107 insertions(+), 86 deletions(-) (limited to 'src') diff --git a/src/afl-analyze.c b/src/afl-analyze.c index e6dd0fca..7c1c269a 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -384,7 +384,7 @@ static void show_legend(void) { /* Interpret and report a pattern in the input file. */ -static void dump_hex(u8 *buf, u32 len, u8 *b_data) { +static void dump_hex(u32 len, u8 *b_data) { u32 i; @@ -678,7 +678,7 @@ static void analyze(char **argv) { } - dump_hex(in_data, in_len, b_data); + dump_hex(in_len, b_data); SAYF("\n"); @@ -700,6 +700,7 @@ static void analyze(char **argv) { static void handle_stop_sig(int sig) { + (void)sig; stop_soon = 1; if (child_pid > 0) { kill(child_pid, SIGKILL); } diff --git a/src/afl-as.c b/src/afl-as.c index f16d6060..4ba4cc71 100644 --- a/src/afl-as.c +++ b/src/afl-as.c @@ -136,7 +136,7 @@ static void edit_params(int argc, char **argv) { as_params[argc] = 0; - for (i = 1; i < argc - 1; i++) { + for (i = 1; (s32)i < argc - 1; i++) { if (!strcmp(argv[i], "--64")) { @@ -591,7 +591,7 @@ int main(int argc, char **argv) { rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid(); // in fast systems where pids can repeat in the same seconds we need this - for (i = 1; i < argc; i++) + for (i = 1; (s32)i < argc; i++) for (j = 0; j < strlen(argv[i]); j++) rand_seed += argv[i][j]; diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 47493eba..15935ab0 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -145,6 +145,10 @@ restart_select: if (likely(sret > 0)) { restart_read: + if (*stop_soon_p) { + // Early return - the user wants to quit. + return 0; + } len_read = read(fd, (u8 *)buf, 4); if (likely(len_read == 4)) { // for speed we put this first @@ -691,7 +695,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } offset = 0; - while (offset < status && (u8)dict[offset] + offset < status) { + while (offset < (u32)status && (u8)dict[offset] + offset < (u32)status) { fsrv->function_ptr(fsrv->function_opt, dict + offset + 1, (u8)dict[offset]); diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 12771cd7..097871c8 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -115,7 +115,7 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len, if (*lptr == '@') { ++lptr; - if (atoi(lptr) > dict_level) { continue; } + if (atoi(lptr) > (s32)dict_level) { continue; } while (isdigit(*lptr)) { ++lptr; @@ -402,7 +402,7 @@ void maybe_add_auto(void *afl_tmp, u8 *mem, u32 len) { while (i--) { - if (*((u32 *)mem) == interesting_32[i] || + if (*((u32 *)mem) == (u32)interesting_32[i] || *((u32 *)mem) == SWAP32(interesting_32[i])) { return; @@ -480,7 +480,7 @@ sort_a_extras: /* Then, sort the top USE_AUTO_EXTRAS entries by size. */ - qsort(afl->a_extras, MIN(USE_AUTO_EXTRAS, afl->a_extras_cnt), + qsort(afl->a_extras, MIN((u32)USE_AUTO_EXTRAS, afl->a_extras_cnt), sizeof(struct extra_data), compare_extras_len); } @@ -494,7 +494,7 @@ void save_auto(afl_state_t *afl) { if (!afl->auto_changed) { return; } afl->auto_changed = 0; - for (i = 0; i < MIN(USE_AUTO_EXTRAS, afl->a_extras_cnt); ++i) { + 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); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 2c17ffbb..1abdcede 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -110,7 +110,7 @@ void bind_to_free_cpu(afl_state_t *afl) { u8 cpu_used[4096] = {0}; u8 lockfile[PATH_MAX] = ""; - u32 i; + s32 i; if (afl->afl_env.afl_no_affinity) { @@ -509,7 +509,7 @@ void read_foreign_testcases(afl_state_t *afl, int first) { afl->stage_cur = 0; afl->stage_max = 0; - for (i = 0; i < nl_cnt; ++i) { + for (i = 0; i < (u32)nl_cnt; ++i) { struct stat st; @@ -667,7 +667,7 @@ void read_testcases(afl_state_t *afl) { } - for (i = 0; i < nl_cnt; ++i) { + for (i = 0; i < (u32)nl_cnt; ++i) { struct stat st; @@ -2147,7 +2147,7 @@ void get_core_count(afl_state_t *afl) { WARNF("System under apparent load, performance may be spotty."); - } else if (cur_runnable + 1 <= afl->cpu_core_count) { + } else if ((s64)cur_runnable + 1 <= (s64)afl->cpu_core_count) { OKF("Try parallel jobs - see %s/parallel_fuzzing.md.", doc_path); @@ -2201,6 +2201,7 @@ void fix_up_sync(afl_state_t *afl) { static void handle_resize(int sig) { + (void)sig; afl_states_clear_screen(); } @@ -2252,6 +2253,7 @@ void check_asan_opts(void) { static void handle_stop_sig(int sig) { + (void)sig; afl_states_stop(); } @@ -2260,6 +2262,7 @@ static void handle_stop_sig(int sig) { static void handle_skipreq(int sig) { + (void)sig; afl_states_request_skip(); } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 1f0bf30e..9d09f6af 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -77,7 +77,7 @@ static int select_algorithm(afl_state_t *afl) { static u32 choose_block_len(afl_state_t *afl, u32 limit) { u32 min_value, max_value; - u32 rlim = MIN(afl->queue_cycle, 3); + u32 rlim = MIN(afl->queue_cycle, (u32)3); if (unlikely(!afl->run_over10m)) { rlim = 1; } @@ -292,7 +292,7 @@ static u8 could_be_interest(u32 old_val, u32 new_val, u8 blen, u8 check_le) { /* See if two-byte insertions over old_val could give us new_val. */ - for (i = 0; i < blen - 1; ++i) { + for (i = 0; (s32)i < blen - 1; ++i) { for (j = 0; j < sizeof(interesting_16) / 2; ++j) { @@ -372,7 +372,9 @@ static void locate_diffs(u8 *ptr1, u8 *ptr2, u32 len, s32 *first, s32 *last) { u8 fuzz_one_original(afl_state_t *afl) { - s32 len, fd, temp_len, i, j; + s32 len, fd, temp_len; + u32 j; + u32 i; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt = 0, prev_cksum; u32 splice_cycle = 0, perf_score = 100, orig_perf, eff_cnt = 1; @@ -862,7 +864,7 @@ u8 fuzz_one_original(afl_state_t *afl) { whole thing as worth fuzzing, since we wouldn't be saving much time anyway. */ - if (eff_cnt != EFF_ALEN(len) && + if (eff_cnt != (u32)EFF_ALEN(len) && eff_cnt * 100 / EFF_ALEN(len) > EFF_MAX_PERC) { memset(eff_map, 1, EFF_ALEN(len)); @@ -893,7 +895,7 @@ u8 fuzz_one_original(afl_state_t *afl) { orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len - 1; ++i) { + for (i = 0; (s32)i < len - 1; ++i) { /* Let's consult the effector map... */ @@ -931,7 +933,7 @@ u8 fuzz_one_original(afl_state_t *afl) { orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len - 3; ++i) { + for (i = 0; (s32)i < len - 3; ++i) { /* Let's consult the effector map... */ if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] && @@ -977,7 +979,7 @@ skip_bitflip: orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len; ++i) { + for (i = 0; i < (u32)len; ++i) { u8 orig = out_buf[i]; @@ -1051,7 +1053,7 @@ skip_bitflip: orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len - 1; ++i) { + for (i = 0; i < (u32)len - 1; ++i) { u16 orig = *(u16 *)(out_buf + i); @@ -1161,7 +1163,7 @@ skip_bitflip: orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len - 3; ++i) { + for (i = 0; i < (u32)len - 3; ++i) { u32 orig = *(u32 *)(out_buf + i); @@ -1202,7 +1204,7 @@ skip_bitflip: } - if ((orig & 0xffff) < j && !could_be_bitflip(r2)) { + if ((orig & 0xffff) < (u32)j && !could_be_bitflip(r2)) { afl->stage_cur_val = -j; *(u32 *)(out_buf + i) = orig - j; @@ -1234,7 +1236,7 @@ skip_bitflip: } - if ((SWAP32(orig) & 0xffff) < j && !could_be_bitflip(r4)) { + if ((SWAP32(orig) & 0xffff) < (u32)j && !could_be_bitflip(r4)) { afl->stage_cur_val = -j; *(u32 *)(out_buf + i) = SWAP32(SWAP32(orig) - j); @@ -1276,7 +1278,7 @@ skip_arith: /* Setting 8-bit integers. */ - for (i = 0; i < len; ++i) { + for (i = 0; i < (u32)len; ++i) { u8 orig = out_buf[i]; @@ -1291,7 +1293,7 @@ skip_arith: afl->stage_cur_byte = i; - for (j = 0; j < sizeof(interesting_8); ++j) { + for (j = 0; j < (u32)sizeof(interesting_8); ++j) { /* Skip if the value could be a product of bitflips or arithmetics. */ @@ -1331,7 +1333,7 @@ skip_arith: orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len - 1; ++i) { + for (i = 0; (s32)i < len - 1; ++i) { u16 orig = *(u16 *)(out_buf + i); @@ -1409,7 +1411,7 @@ skip_arith: orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len - 3; i++) { + for (i = 0; (s32)i < len - 3; i++) { u32 orig = *(u32 *)(out_buf + i); @@ -1496,7 +1498,7 @@ skip_interest: orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len; ++i) { + for (i = 0; i < (u32)len; ++i) { u32 last_len = 0; @@ -1556,7 +1558,7 @@ skip_interest: ex_tmp = ck_maybe_grow(BUF_PARAMS(ex), len + MAX_DICT_FILE); - for (i = 0; i <= len; ++i) { + for (i = 0; i <= (u32)len; ++i) { afl->stage_cur_byte = i; @@ -1602,19 +1604,20 @@ skip_user_extras: afl->stage_name = "auto extras (over)"; afl->stage_short = "ext_AO"; afl->stage_cur = 0; - afl->stage_max = MIN(afl->a_extras_cnt, USE_AUTO_EXTRAS) * len; + afl->stage_max = MIN(afl->a_extras_cnt, (u32)USE_AUTO_EXTRAS) * len; afl->stage_val_type = STAGE_VAL_NONE; orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len; ++i) { + for (i = 0; i < (u32)len; ++i) { u32 last_len = 0; afl->stage_cur_byte = i; - for (j = 0; j < MIN(afl->a_extras_cnt, USE_AUTO_EXTRAS); ++j) { + u32 min_extra_len = MIN(afl->a_extras_cnt, (u32)USE_AUTO_EXTRAS); + for (j = 0; j < min_extra_len; ++j) { /* See the comment in the earlier code; extras are sorted by size. */ @@ -2231,7 +2234,7 @@ havoc_stage: u32 extra_len = afl->a_extras[use_extra].len; u32 insert_at; - if (extra_len > temp_len) { break; } + if ((s32)extra_len > temp_len) { break; } insert_at = rand_below(afl, temp_len - extra_len + 1); memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, @@ -2245,7 +2248,7 @@ havoc_stage: u32 extra_len = afl->extras[use_extra].len; u32 insert_at; - if (extra_len > temp_len) { break; } + if ((s32)extra_len > temp_len) { break; } insert_at = rand_below(afl, temp_len - extra_len + 1); memcpy(out_buf + insert_at, afl->extras[use_extra].data, @@ -2360,7 +2363,7 @@ havoc_stage: u32 copy_from, copy_to, copy_len; copy_len = choose_block_len(afl, new_len - 1); - if (copy_len > temp_len) copy_len = temp_len; + if ((s32)copy_len > temp_len) copy_len = temp_len; copy_from = rand_below(afl, new_len - copy_len + 1); copy_to = rand_below(afl, temp_len - copy_len + 1); @@ -2517,7 +2520,7 @@ retry_splicing: the last differing byte. Bail out if the difference is just a single byte or so. */ - locate_diffs(in_buf, new_buf, MIN(len, target->len), &f_diff, &l_diff); + locate_diffs(in_buf, new_buf, MIN(len, (s64)target->len), &f_diff, &l_diff); if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { goto retry_splicing; } @@ -2587,7 +2590,9 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { } - s32 len, fd, temp_len, i, j; + s32 len, fd, temp_len; + u32 i; + u32 j; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt = 0, cur_ms_lv, prev_cksum; u32 splice_cycle = 0, perf_score = 100, orig_perf, eff_cnt = 1; @@ -2761,9 +2766,9 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { cur_ms_lv = get_cur_time(); if (!(afl->key_puppet == 0 && - ((cur_ms_lv - afl->last_path_time < afl->limit_time_puppet) || + ((cur_ms_lv - afl->last_path_time < (u32)afl->limit_time_puppet) || (afl->last_crash_time != 0 && - cur_ms_lv - afl->last_crash_time < afl->limit_time_puppet) || + cur_ms_lv - afl->last_crash_time < (u32)afl->limit_time_puppet) || afl->last_path_time == 0))) { afl->key_puppet = 1; @@ -3058,7 +3063,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { whole thing as worth fuzzing, since we wouldn't be saving much time anyway. */ - if (eff_cnt != EFF_ALEN(len) && + if (eff_cnt != (u32)EFF_ALEN(len) && eff_cnt * 100 / EFF_ALEN(len) > EFF_MAX_PERC) { memset(eff_map, 1, EFF_ALEN(len)); @@ -3089,7 +3094,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len - 1; ++i) { + for (i = 0; (s32)i < len - 1; ++i) { /* Let's consult the effector map... */ @@ -3127,7 +3132,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len - 3; ++i) { + for (i = 0; (s32)i < len - 3; ++i) { /* Let's consult the effector map... */ if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] && @@ -3173,7 +3178,7 @@ skip_bitflip: orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len; ++i) { + for (i = 0; i < (u32)len; ++i) { u8 orig = out_buf[i]; @@ -3247,7 +3252,7 @@ skip_bitflip: orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len - 1; ++i) { + for (i = 0; (s32)i < len - 1; ++i) { u16 orig = *(u16 *)(out_buf + i); @@ -3357,7 +3362,7 @@ skip_bitflip: orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len - 3; ++i) { + for (i = 0; (s32)i < len - 3; ++i) { u32 orig = *(u32 *)(out_buf + i); @@ -3472,7 +3477,7 @@ skip_arith: /* Setting 8-bit integers. */ - for (i = 0; i < len; ++i) { + for (i = 0; i < (u32)len; ++i) { u8 orig = out_buf[i]; @@ -3527,7 +3532,7 @@ skip_arith: orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len - 1; ++i) { + for (i = 0; (s32)i < len - 1; ++i) { u16 orig = *(u16 *)(out_buf + i); @@ -3605,7 +3610,7 @@ skip_arith: orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len - 3; ++i) { + for (i = 0; (s32)i < len - 3; ++i) { u32 orig = *(u32 *)(out_buf + i); @@ -3692,7 +3697,7 @@ skip_interest: orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len; ++i) { + for (i = 0; i < (u32)len; ++i) { u32 last_len = 0; @@ -3752,7 +3757,7 @@ skip_interest: ex_tmp = ck_maybe_grow(BUF_PARAMS(ex), len + MAX_DICT_FILE); - for (i = 0; i <= len; ++i) { + for (i = 0; i <= (u32)len; ++i) { afl->stage_cur_byte = i; @@ -3798,23 +3803,23 @@ skip_user_extras: afl->stage_name = "auto extras (over)"; afl->stage_short = "ext_AO"; afl->stage_cur = 0; - afl->stage_max = MIN(afl->a_extras_cnt, USE_AUTO_EXTRAS) * len; + afl->stage_max = MIN(afl->a_extras_cnt, (u32)USE_AUTO_EXTRAS) * len; afl->stage_val_type = STAGE_VAL_NONE; orig_hit_cnt = new_hit_cnt; - for (i = 0; i < len; ++i) { + for (i = 0; i < (u32)len; ++i) { u32 last_len = 0; afl->stage_cur_byte = i; - for (j = 0; j < MIN(afl->a_extras_cnt, USE_AUTO_EXTRAS); ++j) { + for (j = 0; j < MIN(afl->a_extras_cnt, (u32)USE_AUTO_EXTRAS); ++j) { /* See the comment in the earlier code; extras are sorted by size. */ - if (afl->a_extras[j].len > len - i || + if ((s32)(afl->a_extras[j].len) > (s32)(len - i) || !memcmp(afl->a_extras[j].data, out_buf + i, afl->a_extras[j].len) || !memchr(eff_map + EFF_APOS(i), 1, EFF_SPAN_ALEN(i, afl->a_extras[j].len))) { @@ -4276,7 +4281,7 @@ pacemaker_fuzzing: u32 use_extra = rand_below(afl, afl->a_extras_cnt); u32 extra_len = afl->a_extras[use_extra].len; - if (extra_len > temp_len) break; + if (extra_len > (u32)temp_len) break; u32 insert_at = rand_below(afl, temp_len - extra_len + 1); memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, @@ -4289,7 +4294,7 @@ pacemaker_fuzzing: u32 use_extra = rand_below(afl, afl->extras_cnt); u32 extra_len = afl->extras[use_extra].len; - if (extra_len > temp_len) break; + if (extra_len > (u32)temp_len) break; u32 insert_at = rand_below(afl, temp_len - extra_len + 1); memcpy(out_buf + insert_at, afl->extras[use_extra].data, @@ -4449,7 +4454,7 @@ pacemaker_fuzzing: retry_splicing_puppet: - if (afl->use_splicing && splice_cycle++ < afl->SPLICE_CYCLES_puppet && + if (afl->use_splicing && splice_cycle++ < (u32)afl->SPLICE_CYCLES_puppet && afl->queued_paths > 1 && afl->queue_cur->len > 1) { struct queue_entry *target; @@ -4519,7 +4524,7 @@ pacemaker_fuzzing: the last differing byte. Bail out if the difference is just a single byte or so. */ - locate_diffs(in_buf, new_buf, MIN(len, target->len), &f_diff, &l_diff); + locate_diffs(in_buf, new_buf, MIN(len, (s32)target->len), &f_diff, &l_diff); if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { @@ -4551,7 +4556,7 @@ pacemaker_fuzzing: abandon_entry: abandon_entry_puppet: - if (splice_cycle >= afl->SPLICE_CYCLES_puppet) { + if ((s64)splice_cycle >= afl->SPLICE_CYCLES_puppet) { afl->SPLICE_CYCLES_puppet = (rand_below( diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 2044c97d..a077469e 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -30,6 +30,9 @@ static void *unsupported(afl_state_t *afl, unsigned int seed) { + (void)afl; + (void)seed; + FATAL("Python Mutator cannot be called twice yet"); return NULL; @@ -111,6 +114,8 @@ static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf, static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { + (void)afl; + if (!module_name) { return NULL; } py_mutator_t *py = calloc(1, sizeof(py_mutator_t)); @@ -247,6 +252,8 @@ void finalize_py_module(void *py_mutator) { static void init_py(afl_state_t *afl, py_mutator_t *py_mutator, unsigned int seed) { + (void)afl; + PyObject *py_args, *py_value; /* Provide the init function a seed for the Python RNG */ diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index cb4c78df..1cfe8802 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -352,7 +352,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - if (use_num && num == pattern) { + if (use_num && (u64) num == pattern) { size_t old_len = endptr - buf_8; size_t num_len = snprintf(NULL, 0, "%lld", num); @@ -659,12 +659,12 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { } -static u8 rtn_extend_encoding(afl_state_t *afl, struct cmp_header *h, +static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, u8 *o_pattern, u32 idx, u8 *orig_buf, u8 *buf, u32 len, u8 *status) { u32 i; - u32 its_len = MIN(32, len - idx); + u32 its_len = MIN((u32)32, len - idx); u8 save[32]; memcpy(save, &buf[idx], its_len); @@ -728,7 +728,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { for (idx = 0; idx < len && fails < 8; ++idx) { - if (unlikely(rtn_extend_encoding(afl, h, o->v0, o->v1, orig_o->v0, idx, + if (unlikely(rtn_extend_encoding(afl, o->v0, o->v1, orig_o->v0, idx, orig_buf, buf, len, &status))) { return 1; @@ -745,7 +745,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { } - if (unlikely(rtn_extend_encoding(afl, h, o->v1, o->v0, orig_o->v1, idx, + if (unlikely(rtn_extend_encoding(afl, o->v1, o->v0, orig_o->v1, idx, orig_buf, buf, len, &status))) { return 1; @@ -853,12 +853,12 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS) { - afl->stage_max += MIN((u32)afl->shm.cmp_map->headers[k].hits, CMP_MAP_H); + afl->stage_max += MIN((u32)(afl->shm.cmp_map->headers[k].hits), (u32)CMP_MAP_H); } else { afl->stage_max += - MIN((u32)afl->shm.cmp_map->headers[k].hits, CMP_MAP_RTN_H); + MIN((u32)(afl->shm.cmp_map->headers[k].hits), (u32)CMP_MAP_RTN_H); } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index ed4a1081..8d652155 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -733,12 +733,12 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { len_p2 = next_pow2(q->len); - remove_len = MAX(len_p2 / TRIM_START_STEPS, TRIM_MIN_BYTES); + remove_len = MAX(len_p2 / TRIM_START_STEPS, (u32)TRIM_MIN_BYTES); /* Continue until the number of steps gets too high or the stepover gets too small. */ - while (remove_len >= MAX(len_p2 / TRIM_END_STEPS, TRIM_MIN_BYTES)) { + while (remove_len >= MAX(len_p2 / TRIM_END_STEPS, (u32)TRIM_MIN_BYTES)) { u32 remove_pos = remove_len; diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 7b30b5ea..aeb290bd 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -890,12 +890,12 @@ void show_stats(afl_state_t *afl) { if (afl->cpu_aff >= 0) { SAYF("%s" cGRA "[cpu%03u:%s%3u%%" cGRA "]\r" cRST, spacing, - MIN(afl->cpu_aff, 999), cpu_color, MIN(cur_utilization, 999)); + MIN(afl->cpu_aff, 999), cpu_color, MIN(cur_utilization, (u32)999)); } else { SAYF("%s" cGRA " [cpu:%s%3u%%" cGRA "]\r" cRST, spacing, cpu_color, - MIN(cur_utilization, 999)); + MIN(cur_utilization, (u32)999)); } @@ -1081,7 +1081,7 @@ void show_init_stats(afl_state_t *afl) { if (afl->non_instrumented_mode && !(afl->afl_env.afl_hang_tmout)) { - afl->hang_tmout = MIN(EXEC_TIMEOUT, afl->fsrv.exec_tmout * 2 + 100); + afl->hang_tmout = MIN((u32)EXEC_TIMEOUT, afl->fsrv.exec_tmout * 2 + 100); } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index c73a76c6..031c4049 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -79,7 +79,7 @@ static void at_exit() { /* Display usage hints. */ -static void usage(afl_state_t *afl, u8 *argv0, int more_help) { +static void usage(u8 *argv0, int more_help) { SAYF( "\n%s [ options ] -- /path/to/fuzzed_app [ ... ]\n\n" @@ -677,7 +677,7 @@ int main(int argc, char **argv_orig, char **envp) { u64 limit_time_puppet2 = afl->limit_time_puppet * 60 * 1000; - if (limit_time_puppet2 < afl->limit_time_puppet) { + if ((s32)limit_time_puppet2 < afl->limit_time_puppet) { FATAL("limit_time overflow"); @@ -811,7 +811,7 @@ int main(int argc, char **argv_orig, char **envp) { if (optind == argc || !afl->in_dir || !afl->out_dir || show_help) { - usage(afl, argv[0], show_help); + usage(argv[0], show_help); } diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 71e975a1..4962006e 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -256,8 +256,7 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { /* Execute target application. */ -static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, char **argv, - u8 *mem, u32 len) { +static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, u8 *mem, u32 len) { afl_fsrv_write_to_testcase(fsrv, mem, len); @@ -444,6 +443,7 @@ static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) { static void handle_stop_sig(int sig) { + (void)sig; stop_soon = 1; afl_fsrv_killall(); @@ -1016,7 +1016,7 @@ int main(int argc, char **argv_orig, char **envp) { } - showmap_run_target_forkserver(fsrv, use_argv, in_data, in_len); + showmap_run_target_forkserver(fsrv, in_data, in_len); ck_free(in_data); tcnt = write_results_to_file(fsrv, outfile); diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 68fcdd14..b50d8597 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -250,7 +250,7 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) { /* Execute target application. Returns 0 if the changes are a dud, or 1 if they should be kept. */ -static u8 tmin_run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len, +static u8 tmin_run_target(afl_forkserver_t *fsrv, u8 *mem, u32 len, u8 first_run) { afl_fsrv_write_to_testcase(fsrv, mem, len); @@ -342,7 +342,7 @@ static u8 tmin_run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len, /* Actually minimize! */ -static void minimize(afl_forkserver_t *fsrv, char **argv) { +static void minimize(afl_forkserver_t *fsrv) { static u32 alpha_map[256]; @@ -380,7 +380,7 @@ static void minimize(afl_forkserver_t *fsrv, char **argv) { memset(tmp_buf + set_pos, '0', use_len); u8 res; - res = tmin_run_target(fsrv, argv, tmp_buf, in_len, 0); + res = tmin_run_target(fsrv, tmp_buf, in_len, 0); if (res) { @@ -453,7 +453,7 @@ next_del_blksize: /* Tail */ memcpy(tmp_buf + del_pos, in_data + del_pos + del_len, tail_len); - res = tmin_run_target(fsrv, argv, tmp_buf, del_pos + tail_len, 0); + res = tmin_run_target(fsrv, tmp_buf, del_pos + tail_len, 0); if (res) { @@ -524,7 +524,7 @@ next_del_blksize: } - res = tmin_run_target(fsrv, argv, tmp_buf, in_len, 0); + res = tmin_run_target(fsrv, tmp_buf, in_len, 0); if (res) { @@ -560,7 +560,7 @@ next_del_blksize: if (orig == '0') { continue; } tmp_buf[i] = '0'; - res = tmin_run_target(fsrv, argv, tmp_buf, in_len, 0); + res = tmin_run_target(fsrv, tmp_buf, in_len, 0); if (res) { @@ -623,6 +623,7 @@ finalize_all: static void handle_stop_sig(int sig) { + (void)sig; stop_soon = 1; afl_fsrv_killall(); @@ -1131,7 +1132,7 @@ int main(int argc, char **argv_orig, char **envp) { ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...", fsrv->mem_limit, fsrv->exec_tmout, edges_only ? ", edges only" : ""); - tmin_run_target(fsrv, use_argv, in_data, in_len, 1); + tmin_run_target(fsrv, in_data, in_len, 1); if (hang_mode && !fsrv->last_run_timed_out) { @@ -1169,7 +1170,7 @@ int main(int argc, char **argv_orig, char **envp) { } - minimize(fsrv, use_argv); + minimize(fsrv); ACTF("Writing output to '%s'...", output_file); -- cgit v1.2.3 From 699ebaa8e210e0d72ad7e3ac6f4a580cfbe37eae Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 7 Aug 2020 17:32:41 +0200 Subject: code format --- src/afl-forkserver.c | 6 +++++- src/afl-fuzz-one.c | 6 ++++-- src/afl-fuzz-redqueen.c | 11 ++++++----- src/afl-showmap.c | 3 ++- 4 files changed, 17 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 15935ab0..752641d7 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -146,9 +146,12 @@ restart_select: restart_read: if (*stop_soon_p) { + // Early return - the user wants to quit. return 0; + } + len_read = read(fd, (u8 *)buf, 4); if (likely(len_read == 4)) { // for speed we put this first @@ -695,7 +698,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } offset = 0; - while (offset < (u32)status && (u8)dict[offset] + offset < (u32)status) { + while (offset < (u32)status && + (u8)dict[offset] + offset < (u32)status) { fsrv->function_ptr(fsrv->function_opt, dict + offset + 1, (u8)dict[offset]); diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 9d09f6af..74e09ee3 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -4454,7 +4454,8 @@ pacemaker_fuzzing: retry_splicing_puppet: - if (afl->use_splicing && splice_cycle++ < (u32)afl->SPLICE_CYCLES_puppet && + if (afl->use_splicing && + splice_cycle++ < (u32)afl->SPLICE_CYCLES_puppet && afl->queued_paths > 1 && afl->queue_cur->len > 1) { struct queue_entry *target; @@ -4524,7 +4525,8 @@ pacemaker_fuzzing: the last differing byte. Bail out if the difference is just a single byte or so. */ - locate_diffs(in_buf, new_buf, MIN(len, (s32)target->len), &f_diff, &l_diff); + locate_diffs(in_buf, new_buf, MIN(len, (s32)target->len), &f_diff, + &l_diff); if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 1cfe8802..9716be95 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -352,7 +352,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - if (use_num && (u64) num == pattern) { + if (use_num && (u64)num == pattern) { size_t old_len = endptr - buf_8; size_t num_len = snprintf(NULL, 0, "%lld", num); @@ -659,9 +659,9 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { } -static u8 rtn_extend_encoding(afl_state_t *afl, - u8 *pattern, u8 *repl, u8 *o_pattern, u32 idx, - u8 *orig_buf, u8 *buf, u32 len, u8 *status) { +static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, + u8 *o_pattern, u32 idx, u8 *orig_buf, u8 *buf, + u32 len, u8 *status) { u32 i; u32 its_len = MIN((u32)32, len - idx); @@ -853,7 +853,8 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS) { - afl->stage_max += MIN((u32)(afl->shm.cmp_map->headers[k].hits), (u32)CMP_MAP_H); + afl->stage_max += + MIN((u32)(afl->shm.cmp_map->headers[k].hits), (u32)CMP_MAP_H); } else { diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 4962006e..0aa116e5 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -256,7 +256,8 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { /* Execute target application. */ -static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, u8 *mem, u32 len) { +static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, u8 *mem, + u32 len) { afl_fsrv_write_to_testcase(fsrv, mem, len); -- cgit v1.2.3 From 27abecbff5021d9eaa226a7f370e6b8f14ec9601 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Fri, 7 Aug 2020 21:07:05 +0200 Subject: compile fixes on 32-bit OSs --- src/afl-as.c | 6 +++--- src/afl-fuzz-init.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-as.c b/src/afl-as.c index 4ba4cc71..0ed47d8c 100644 --- a/src/afl-as.c +++ b/src/afl-as.c @@ -407,7 +407,7 @@ static void add_instrumentation(void) { if (line[0] == '\t') { - if (line[1] == 'j' && line[2] != 'm' && R(100) < inst_ratio) { + if (line[1] == 'j' && line[2] != 'm' && R(100) < (long)inst_ratio) { fprintf(outf, use_64bit ? trampoline_fmt_64 : trampoline_fmt_32, R(MAP_SIZE)); @@ -449,7 +449,7 @@ static void add_instrumentation(void) { /* Apple: L / LBB */ if ((isdigit(line[1]) || (clang_mode && !strncmp(line, "LBB", 3))) && - R(100) < inst_ratio) { + R(100) < (long)inst_ratio) { #else @@ -457,7 +457,7 @@ static void add_instrumentation(void) { if ((isdigit(line[2]) || (clang_mode && !strncmp(line + 1, "LBB", 3))) && - R(100) < inst_ratio) { + R(100) < (long)inst_ratio) { #endif /* __APPLE__ */ diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 1abdcede..350a8599 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -762,7 +762,7 @@ void perform_dry_run(afl_state_t *afl) { use_mem = ck_alloc_nozero(q->len); - if (read(fd, use_mem, q->len) != q->len) { + if (read(fd, use_mem, q->len) != (ssize_t)q->len) { FATAL("Short read from '%s'", q->fname); -- cgit v1.2.3 From 9a1d526ed408cbd7d681be15c5512032f7632887 Mon Sep 17 00:00:00 2001 From: murx- Date: Sat, 8 Aug 2020 18:34:54 +0200 Subject: Add support for specific custom mutator name --- src/afl-fuzz-mutators.c | 1 + src/afl-fuzz-one.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index b30106a0..0fa646f9 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -142,6 +142,7 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { struct custom_mutator *mutator = ck_alloc(sizeof(struct custom_mutator)); mutator->name = fn; + mutator->name_short = strrchr(fn, '/') + 1; ACTF("Loading custom mutator library from '%s'...", fn); dh = dlopen(fn, RTLD_NOW); diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 74e09ee3..452c5298 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1683,6 +1683,8 @@ custom_mutator_stage: has_custom_fuzz = true; + afl->stage_short = el->name_short; + for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { -- cgit v1.2.3 From e4a0237cbc745552a5b21a2450d7ab55ee98759d Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 9 Aug 2020 00:35:12 +0200 Subject: step 1 --- src/afl-common.c | 1 + src/afl-forkserver.c | 15 +++++++++++++-- src/afl-fuzz-bitmap.c | 32 ++++++++++++++++++++++++++++++++ src/afl-fuzz-run.c | 13 +++++++++++++ src/afl-fuzz.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 106 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 367dec72..134d3180 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -138,6 +138,7 @@ void argv_cpy_free(char **argv) { } + /* Rewrite argv for QEMU. */ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 752641d7..b4f92e5b 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -481,6 +481,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "handle_sigill=0", 0); +fprintf(stderr, "init %p\n", fsrv->init_child_func); fsrv->init_child_func(fsrv, argv); /* Use a distinctive bitmap signature to tell the parent about execv() @@ -496,10 +497,20 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, char pid_buf[16]; sprintf(pid_buf, "%d", fsrv->fsrv_pid); - if (fsrv->cmplog_binary) + + if (fsrv->qemu_mode == 2) { + + setenv("__AFL_TARGET_PID3", pid_buf, 1); + + } else if (fsrv->cmplog_binary) { + setenv("__AFL_TARGET_PID2", pid_buf, 1); - else + + } else { + setenv("__AFL_TARGET_PID1", pid_buf, 1); + + } /* Close the unneeded endpoints. */ diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index aa8d5a18..9cb1b83f 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -177,6 +177,38 @@ u32 count_bits(afl_state_t *afl, u8 *mem) { } +u32 count_bits_len(afl_state_t *afl, u8 *mem, u32 len) { + + u32 *ptr = (u32 *)mem; + u32 i = (len >> 2); + u32 ret = 0; + + if (len % 4) i++; + + while (i--) { + + u32 v = *(ptr++); + + /* This gets called on the inverse, virgin bitmap; optimize for sparse + data. */ + + if (v == 0xffffffff) { + + ret += 32; + continue; + + } + + v -= ((v >> 1) & 0x55555555); + v = (v & 0x33333333) + ((v >> 2) & 0x33333333); + ret += (((v + (v >> 4)) & 0xF0F0F0F) * 0x01010101) >> 24; + + } + + return ret; + +} + /* Count the number of bytes set in the bitmap. Called fairly sporadically, mostly to update the status screen or calibrate and examine confirmed new paths. */ diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 8d652155..207b3046 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -471,6 +471,19 @@ abort_calibration: afl->stage_cur = old_sc; afl->stage_max = old_sm; + /* if taint mode was selected, run the taint */ + + if (afl->fsrv.taint_mode) { + write_to_testcase(afl, use_mem, q->len); + if (afl_fsrv_run_target(&afl->taint_fsrv, use_tmout, &afl->stop_soon) == 0) { + u32 len = q->len / 8; + if (q->len % 8) len++; + u32 bits = count_bits_len(afl, afl->taint_fsrv.trace_bits, len); + if (afl->debug) fprintf(stderr, "Debug: tainted bytes: %u\n", bits); + + } + } + if (!first_run) { show_stats(afl); } return fault; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 031c4049..bc780b55 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -53,6 +53,9 @@ static void at_exit() { ptr = getenv("__AFL_TARGET_PID2"); if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL); + ptr = getenv("__AFL_TARGET_PID3"); + if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL); + i = 0; while (list[i] != NULL) { @@ -89,6 +92,7 @@ static void usage(u8 *argv0, int more_help) { " -o dir - output directory for fuzzer findings\n\n" "Execution control settings:\n" + " -A - use first level taint analysis (see qemu_taint/README.md)\n" " -p schedule - power schedules compute a seed's performance score. " " 0) { + "+b:c:i:I:o:f:F:m:t:T:dDnCB:S:M:x:QANUWe:p:s:V:E:L:hRP:")) > 0) { switch (opt) { + case 'A': + afl->fsrv.taint_mode = 1; + if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_QEMU; } + break; + case 'I': afl->infoexec = optarg; break; @@ -485,7 +494,7 @@ int main(int argc, char **argv_orig, char **envp) { if (!optarg) { FATAL("Wrong usage of -m"); } - if (!strcmp(optarg, "none")) { + if (!strcmp(optarg, "none") || !strcmp(optarg, "0")) { afl->fsrv.mem_limit = 0; break; @@ -815,6 +824,14 @@ int main(int argc, char **argv_orig, char **envp) { } + if (afl->fsrv.taint_mode && afl->fsrv.map_size < (MAX_FILE / 8) + 1) { + + afl->shm.map_size = (MAX_FILE / 8); + if (MAX_FILE % 8) afl->shm.map_size++; + afl->fsrv.map_size = afl->shm.map_size; + + } + if (!mem_limit_given && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260; OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" " @@ -869,6 +886,7 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->crash_mode) { FATAL("-C and -n are mutually exclusive"); } if (afl->fsrv.qemu_mode) { FATAL("-Q and -n are mutually exclusive"); } if (afl->unicorn_mode) { FATAL("-U and -n are mutually exclusive"); } + if (afl->fsrv.taint_mode) { FATAL("-A and -n are mutually exclusive"); } } @@ -969,7 +987,7 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->afl_env.afl_preload) { - if (afl->fsrv.qemu_mode) { + if (afl->fsrv.qemu_mode || afl->fsrv.taint_mode) { u8 *qemu_preload = getenv("QEMU_SET_ENV"); u8 *afl_preload = getenv("AFL_PRELOAD"); @@ -1220,7 +1238,6 @@ int main(int argc, char **argv_orig, char **envp) { ACTF("Spawning cmplog forkserver"); afl_fsrv_init_dup(&afl->cmplog_fsrv, &afl->fsrv); - // TODO: this is semi-nice afl->cmplog_fsrv.trace_bits = afl->fsrv.trace_bits; afl->cmplog_fsrv.qemu_mode = afl->fsrv.qemu_mode; afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary; @@ -1230,6 +1247,29 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Cmplog forkserver successfully started"); } + + if (afl->fsrv.taint_mode) { + + ACTF("Spawning qemu_taint forkserver"); + afl_fsrv_init_dup(&afl->taint_fsrv, &afl->fsrv); + afl->taint_fsrv.qemu_mode = 2; + afl->taint_fsrv.trace_bits = afl->fsrv.trace_bits; + ck_free(afl->taint_fsrv.target_path); + afl->taint_fsrv.target_path = ck_strdup(afl->fsrv.target_path); + afl->argv_taint = get_qemu_argv(argv[0], &afl->taint_fsrv.target_path, + argc - optind, argv + optind); + u32 len = strlen(afl->taint_fsrv.target_path); + strcpy(afl->taint_fsrv.target_path + len - 5, "taint"); + strcpy((afl->argv_taint[0]) + len - 5, "taint"); + if (afl->fsrv.use_stdin) + unsetenv("AFL_TAINT_INPUT"); + else + setenv("AFL_TAINT_INPUT", afl->fsrv.out_file, 1); + afl_fsrv_start(&afl->taint_fsrv, afl->argv_taint, &afl->stop_soon, + afl->afl_env.afl_debug_child_output); + OKF("Taint forkserver successfully started"); + + } perform_dry_run(afl); @@ -1493,8 +1533,11 @@ stop_fuzzing: } + if (afl->cmplog_binary) afl_fsrv_deinit(&afl->cmplog_fsrv); + if (afl->fsrv.taint_mode) afl_fsrv_deinit(&afl->taint_fsrv); afl_fsrv_deinit(&afl->fsrv); if (afl->orig_cmdline) { ck_free(afl->orig_cmdline); } + if (afl->argv_taint) { ck_free(afl->argv_taint); } ck_free(afl->fsrv.target_path); ck_free(afl->fsrv.out_file); ck_free(afl->sync_id); -- cgit v1.2.3 From 0bb59ba11606e0382126304f78507efe7d62fd6b Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 9 Aug 2020 01:09:26 +0200 Subject: code format --- src/afl-common.c | 140 +++++++++++++++++---------------------------------- src/afl-forkserver.c | 11 ++-- src/afl-fuzz-run.c | 8 ++- src/afl-fuzz.c | 25 ++++++--- 4 files changed, 75 insertions(+), 109 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 134d3180..c0202821 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -138,32 +138,19 @@ void argv_cpy_free(char **argv) { } +u8 *find_binary_own_loc(u8 *fname, u8 *own_loc) { -/* Rewrite argv for QEMU. */ - -char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { - - char **new_argv = ck_alloc(sizeof(char *) * (argc + 4)); - u8 * tmp, *cp = NULL, *rsl, *own_copy; - - memcpy(&new_argv[3], &argv[1], (int)(sizeof(char *)) * (argc - 1)); - new_argv[argc - 1] = NULL; - - new_argv[2] = *target_path_p; - new_argv[1] = "--"; - - /* Now we need to actually find the QEMU binary to put in argv[0]. */ + u8 *tmp, *rsl, *own_copy, *cp; tmp = getenv("AFL_PATH"); if (tmp) { - cp = alloc_printf("%s/afl-qemu-trace", tmp); + cp = alloc_printf("%s/%s", tmp, fname); if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); } - *target_path_p = new_argv[0] = cp; - return new_argv; + return cp; } @@ -174,15 +161,10 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { *rsl = 0; - cp = alloc_printf("%s/afl-qemu-trace", own_copy); + cp = alloc_printf("%s/%s", own_copy, fname); ck_free(own_copy); - if (!access(cp, X_OK)) { - - *target_path_p = new_argv[0] = cp; - return new_argv; - - } + if (!access(cp, X_OK)) { return cp; } } else { @@ -190,11 +172,35 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { } - if (!access(BIN_PATH "/afl-qemu-trace", X_OK)) { + cp = alloc_printf("%s/%s", BIN_PATH, fname); + if (!access(cp, X_OK)) { return cp; } + + ck_free(cp); + + return NULL; - if (cp) { ck_free(cp); } - *target_path_p = new_argv[0] = ck_strdup(BIN_PATH "/afl-qemu-trace"); +} + +/* Rewrite argv for QEMU. */ + +char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { + + char **new_argv = ck_alloc(sizeof(char *) * (argc + 4)); + u8 * cp = NULL; + + memcpy(&new_argv[3], &argv[1], (int)(sizeof(char *)) * (argc - 1)); + new_argv[argc - 1] = NULL; + new_argv[2] = *target_path_p; + new_argv[1] = "--"; + + /* Now we need to actually find the QEMU binary to put in argv[0]. */ + + cp = find_binary_own_loc("afl-qemu-trace", own_loc); + + if (cp) { + + *target_path_p = new_argv[0] = cp; return new_argv; } @@ -235,66 +241,16 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { /* Now we need to actually find the QEMU binary to put in argv[0]. */ - tmp = getenv("AFL_PATH"); - - if (tmp) { + cp = find_binary_own_loc("afl-qemu-trace", own_loc); - cp = alloc_printf("%s/afl-qemu-trace", tmp); - - if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); } + if (cp) { ck_free(cp); + cp = find_binary_own_loc("afl-wine-trace", own_loc); - cp = alloc_printf("%s/afl-wine-trace", tmp); + if (cp) { - if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); } - - *target_path_p = new_argv[0] = cp; - return new_argv; - - } - - own_copy = ck_strdup(own_loc); - rsl = strrchr(own_copy, '/'); - - if (rsl) { - - *rsl = 0; - - cp = alloc_printf("%s/afl-qemu-trace", own_copy); - - if (cp && !access(cp, X_OK)) { - - ck_free(cp); - - cp = alloc_printf("%s/afl-wine-trace", own_copy); - - if (!access(cp, X_OK)) { - - *target_path_p = new_argv[0] = cp; - return new_argv; - - } - - } - - ck_free(own_copy); - - } else { - - ck_free(own_copy); - - } - - u8 *ncp = BIN_PATH "/afl-qemu-trace"; - - if (!access(ncp, X_OK)) { - - ncp = BIN_PATH "/afl-wine-trace"; - - if (!access(ncp, X_OK)) { - - *target_path_p = new_argv[0] = ck_strdup(ncp); + *target_path_p = new_argv[0] = cp; return new_argv; } @@ -302,25 +258,21 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { } SAYF("\n" cLRD "[-] " cRST - "Oops, unable to find the '%s' binary. The binary must be " - "built\n" - " separately by following the instructions in " - "qemu_mode/README.md. " - "If you\n" - " already have the binary installed, you may need to specify " - "AFL_PATH in the\n" - " environment.\n\n" - + "Oops, unable to find the afl-qemu-trace and afl-wine-trace binaries.\n" + "The afl-qemu-trace binary must be built separately by following the " + "instructions\n" + "in qemu_mode/README.md. If you already have the binary installed, you " + "may need\n" + "to specify the location via AFL_PATH in the environment.\n\n" " Of course, even without QEMU, afl-fuzz can still work with " "binaries that are\n" " instrumented at compile time with afl-gcc. It is also possible to " "use it as a\n" " traditional non-instrumented fuzzer by specifying '-n' in the " "command " - "line.\n", - ncp); + "line.\n"); - FATAL("Failed to locate '%s'.", ncp); + FATAL("Failed to locate 'afl-qemu-trace' and 'afl-wine-trace'."); } diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index b4f92e5b..eeb2f8c3 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -481,7 +481,6 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "handle_sigill=0", 0); -fprintf(stderr, "init %p\n", fsrv->init_child_func); fsrv->init_child_func(fsrv, argv); /* Use a distinctive bitmap signature to tell the parent about execv() @@ -497,19 +496,19 @@ fprintf(stderr, "init %p\n", fsrv->init_child_func); char pid_buf[16]; sprintf(pid_buf, "%d", fsrv->fsrv_pid); - + if (fsrv->qemu_mode == 2) { setenv("__AFL_TARGET_PID3", pid_buf, 1); } else if (fsrv->cmplog_binary) { - + setenv("__AFL_TARGET_PID2", pid_buf, 1); - + } else { - + setenv("__AFL_TARGET_PID1", pid_buf, 1); - + } /* Close the unneeded endpoints. */ diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 207b3046..badc2239 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -472,16 +472,20 @@ abort_calibration: afl->stage_max = old_sm; /* if taint mode was selected, run the taint */ - + if (afl->fsrv.taint_mode) { + write_to_testcase(afl, use_mem, q->len); - if (afl_fsrv_run_target(&afl->taint_fsrv, use_tmout, &afl->stop_soon) == 0) { + if (afl_fsrv_run_target(&afl->taint_fsrv, use_tmout, &afl->stop_soon) == + 0) { + u32 len = q->len / 8; if (q->len % 8) len++; u32 bits = count_bits_len(afl, afl->taint_fsrv.trace_bits, len); if (afl->debug) fprintf(stderr, "Debug: tainted bytes: %u\n", bits); } + } if (!first_run) { show_stats(afl); } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index bc780b55..684b123e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -92,7 +92,8 @@ static void usage(u8 *argv0, int more_help) { " -o dir - output directory for fuzzer findings\n\n" "Execution control settings:\n" - " -A - use first level taint analysis (see qemu_taint/README.md)\n" + " -A - use first level taint analysis (see " + "qemu_taint/README.md)\n" " -p schedule - power schedules compute a seed's performance score. " "fsrv.taint_mode) { ACTF("Spawning qemu_taint forkserver"); @@ -1256,11 +1257,21 @@ int main(int argc, char **argv_orig, char **envp) { afl->taint_fsrv.trace_bits = afl->fsrv.trace_bits; ck_free(afl->taint_fsrv.target_path); afl->taint_fsrv.target_path = ck_strdup(afl->fsrv.target_path); - afl->argv_taint = get_qemu_argv(argv[0], &afl->taint_fsrv.target_path, - argc - optind, argv + optind); - u32 len = strlen(afl->taint_fsrv.target_path); - strcpy(afl->taint_fsrv.target_path + len - 5, "taint"); - strcpy((afl->argv_taint[0]) + len - 5, "taint"); + afl->argv_taint = ck_alloc(sizeof(char *) * (argc + 4 - optind)); + afl->argv_taint[0] = find_binary_own_loc("afl-qemu-taint", argv[0]); + if (!afl->argv_taint[0]) + FATAL( + "Cannot find 'afl-qemu-taint', read qemu_taint/README.md on how to " + "build it."); + u32 idx = optind - 1, offset = 0; + do { + + idx++; + offset++; + afl->argv_taint[offset] = argv[idx]; + + } while (argv[idx] != NULL); + if (afl->fsrv.use_stdin) unsetenv("AFL_TAINT_INPUT"); else -- cgit v1.2.3 From a1129b67c22ff54e25d457efbe44b3ab11851b5b Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 9 Aug 2020 12:15:36 +0200 Subject: changes --- src/afl-fuzz-bitmap.c | 23 +++++++++++++++++++++++ src/afl-fuzz-run.c | 9 +++++---- src/afl-fuzz.c | 6 ++---- 3 files changed, 30 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 9cb1b83f..8aaa4ae1 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -235,6 +235,29 @@ u32 count_bytes(afl_state_t *afl, u8 *mem) { } +u32 count_bytes_len(afl_state_t *afl, u8 *mem, u32 len) { + + u32 *ptr = (u32 *)mem; + u32 i = (len >> 2); + u32 ret = 0; + + while (i--) { + + u32 v = *(ptr++); + + if (!v) { continue; } + if (v & 0x000000ff) { ++ret; } + if (v & 0x0000ff00) { ++ret; } + if (v & 0x00ff0000) { ++ret; } + if (v & 0xff000000) { ++ret; } + + } + + return ret; + +} + + /* Count the number of non-255 bytes set in the bitmap. Used strictly for the status screen, several calls per second or so. */ diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index badc2239..b325f788 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -479,10 +479,11 @@ abort_calibration: if (afl_fsrv_run_target(&afl->taint_fsrv, use_tmout, &afl->stop_soon) == 0) { - u32 len = q->len / 8; - if (q->len % 8) len++; - u32 bits = count_bits_len(afl, afl->taint_fsrv.trace_bits, len); - if (afl->debug) fprintf(stderr, "Debug: tainted bytes: %u\n", bits); + u32 len = q->len; + if (len % 4) + len = len + 4 - (q->len % 4); + u32 bytes = count_bytes_len(afl, afl->taint_fsrv.trace_bits, len); + if (afl->debug) fprintf(stderr, "Debug: tainted bytes: %u\n", bytes); } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 684b123e..4a3d2e97 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -825,11 +825,9 @@ int main(int argc, char **argv_orig, char **envp) { } - if (afl->fsrv.taint_mode && afl->fsrv.map_size < (MAX_FILE / 8) + 1) { + if (afl->fsrv.taint_mode && afl->fsrv.map_size < MAX_FILE) { - afl->shm.map_size = (MAX_FILE / 8); - if (MAX_FILE % 8) afl->shm.map_size++; - afl->fsrv.map_size = afl->shm.map_size; + afl->fsrv.map_size = afl->shm.map_size = MAX_FILE; } -- cgit v1.2.3 From 32db31b5550b73cbb20abb5e862fb08f86681ace Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 9 Aug 2020 12:35:52 +0200 Subject: fixes --- src/afl-fuzz-bitmap.c | 1 - src/afl-fuzz-run.c | 6 +++--- src/afl-fuzz-state.c | 30 +++++++++++++++++++----------- src/afl-fuzz.c | 6 ++++-- 4 files changed, 26 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 8aaa4ae1..11a3f121 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -257,7 +257,6 @@ u32 count_bytes_len(afl_state_t *afl, u8 *mem, u32 len) { } - /* Count the number of non-255 bytes set in the bitmap. Used strictly for the status screen, several calls per second or so. */ diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index b325f788..89ae0424 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -480,10 +480,10 @@ abort_calibration: 0) { u32 len = q->len; - if (len % 4) - len = len + 4 - (q->len % 4); + if (len % 4) len = len + 4 - (q->len % 4); u32 bytes = count_bytes_len(afl, afl->taint_fsrv.trace_bits, len); - if (afl->debug) fprintf(stderr, "Debug: tainted bytes: %u\n", bytes); + if (afl->debug) + fprintf(stderr, "Debug: tainted %u out of %u bytes\n", bytes, q->len); } diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index e2d62bc6..aab785e1 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -75,7 +75,7 @@ static list_t afl_states = {.element_prealloc_count = 0}; /* Initializes an afl_state_t. */ -void afl_state_init(afl_state_t *afl, uint32_t map_size) { +void afl_state_init_1(afl_state_t *afl, uint32_t map_size) { /* thanks to this memset, growing vars like out_buf and out_size are NULL/0 by default. */ @@ -100,16 +100,6 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->cpu_aff = -1; /* Selected CPU core */ #endif /* HAVE_AFFINITY */ - afl->virgin_bits = ck_alloc(map_size); - afl->virgin_tmout = ck_alloc(map_size); - afl->virgin_crash = ck_alloc(map_size); - afl->var_bytes = ck_alloc(map_size); - afl->top_rated = ck_alloc(map_size * sizeof(void *)); - afl->clean_trace = ck_alloc(map_size); - afl->clean_trace_custom = ck_alloc(map_size); - afl->first_trace = ck_alloc(map_size); - afl->map_tmp_buf = ck_alloc(map_size); - afl->fsrv.use_stdin = 1; afl->fsrv.map_size = map_size; afl->fsrv.function_opt = (u8 *)afl; @@ -160,6 +150,24 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { } +void afl_state_init_2(afl_state_t *afl, uint32_t map_size) { + + afl->shm.map_size = map_size ? map_size : MAP_SIZE; + + afl->virgin_bits = ck_alloc(map_size); + afl->virgin_tmout = ck_alloc(map_size); + afl->virgin_crash = ck_alloc(map_size); + afl->var_bytes = ck_alloc(map_size); + afl->top_rated = ck_alloc(map_size * sizeof(void *)); + afl->clean_trace = ck_alloc(map_size); + afl->clean_trace_custom = ck_alloc(map_size); + afl->first_trace = ck_alloc(map_size); + afl->map_tmp_buf = ck_alloc(map_size); + + afl->fsrv.map_size = map_size; + +} + /*This sets up the environment variables for afl-fuzz into the afl_state * struct*/ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 4a3d2e97..93ab90e2 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -262,7 +262,7 @@ int main(int argc, char **argv_orig, char **envp) { if (get_afl_env("AFL_DEBUG")) { debug = afl->debug = 1; } map_size = get_map_size(); - afl_state_init(afl, map_size); + afl_state_init_1(afl, map_size); afl->debug = debug; afl_fsrv_init(&afl->fsrv); @@ -827,10 +827,12 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->fsrv.taint_mode && afl->fsrv.map_size < MAX_FILE) { - afl->fsrv.map_size = afl->shm.map_size = MAX_FILE; + map_size = afl->fsrv.map_size = afl->shm.map_size = MAX_FILE; } + afl_state_init_2(afl, map_size); + if (!mem_limit_given && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260; OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" " -- cgit v1.2.3 From b60663c0318b8baf21b36b549d765ddd2eeeb54e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 9 Aug 2020 18:48:12 +0200 Subject: taint integration done --- src/afl-common.c | 2 +- src/afl-forkserver.c | 3 +- src/afl-fuzz-bitmap.c | 2 +- src/afl-fuzz-init.c | 28 +++++++++- src/afl-fuzz-queue.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/afl-fuzz-run.c | 83 +++++++++++++-------------- src/afl-fuzz.c | 25 +++++++-- 7 files changed, 234 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index c0202821..e01bde3c 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -232,7 +232,7 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { char **new_argv = ck_alloc(sizeof(char *) * (argc + 3)); - u8 * tmp, *cp = NULL, *rsl, *own_copy; + u8 * cp = NULL; memcpy(&new_argv[2], &argv[1], (int)(sizeof(char *)) * (argc - 1)); new_argv[argc - 1] = NULL; diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index eeb2f8c3..4dc5e438 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -933,7 +933,7 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { } else { - s32 fd = fsrv->out_fd; + s32 fd; if (fsrv->out_file) { @@ -952,6 +952,7 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { } else { + fd = fsrv->out_fd; lseek(fd, 0, SEEK_SET); } diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 11a3f121..d4ee36e1 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -648,7 +648,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #endif /* ^!SIMPLE_FILES */ - add_to_queue(afl, queue_fn, len, 0); + add_to_queue(afl, queue_fn, mem, len, afl->queue_top, 0); if (hnb == 2) { diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 350a8599..350a3b4c 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -712,7 +712,7 @@ void read_testcases(afl_state_t *afl) { if (!access(dfn, F_OK)) { passed_det = 1; } - add_to_queue(afl, fn2, st.st_size, passed_det); + add_to_queue(afl, fn2, NULL, st.st_size, NULL, passed_det); } @@ -960,6 +960,9 @@ void perform_dry_run(afl_state_t *afl) { } + /* perform taint gathering on the input seed */ + perform_taint_run(afl, q, q->fname, use_mem, q->len); + q = q->next; } @@ -1438,6 +1441,10 @@ static void handle_existing_out_dir(afl_state_t *afl) { u8 *orig_q = alloc_printf("%s/queue", afl->out_dir); + u8 *fnt = alloc_printf("%s/taint", afl->out_dir); + mkdir(fnt, 0755); // ignore errors + ck_free(fnt); + afl->in_dir = alloc_printf("%s/_resume", afl->out_dir); rename(orig_q, afl->in_dir); /* Ignore errors */ @@ -1494,6 +1501,15 @@ static void handle_existing_out_dir(afl_state_t *afl) { if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); + if (afl->fsrv.taint_mode) { + + fn = alloc_printf("%s/taint", afl->out_dir); + mkdir(fn, 0755); // ignore errors + if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } + ck_free(fn); + + } + /* All right, let's do out_dir>/crashes/id:* and * out_dir>/hangs/id:*. */ @@ -1721,6 +1737,16 @@ void setup_dirs_fds(afl_state_t *afl) { if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); } ck_free(tmp); + /* Taint directory if taint_mode. */ + + if (afl->fsrv.taint_mode) { + + tmp = alloc_printf("%s/taint", afl->out_dir); + if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); } + ck_free(tmp); + + } + /* Top-level directory for queue metadata used for session resume and related tasks. */ diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index f35df914..36ec0896 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -103,6 +103,139 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) { } +void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname, + u8 *mem, u32 len) { + + u8 * ptr, *fn = fname; + u32 bytes = 0, plen = len; + s32 fd = -1; + struct queue_entry *prev = q->prev; + + if (plen % 4) plen = plen + 4 - (len % 4); + + if ((ptr = strrchr(fname, '/')) != NULL) fn = ptr + 1; + q->fname_taint = alloc_printf("%s/taint/%s", afl->out_dir, fn); + + if (q->fname_taint) { + + afl->taint_fsrv.map_size = plen; // speed :) + write_to_testcase(afl, mem, len); + if (afl_fsrv_run_target(&afl->taint_fsrv, afl->fsrv.exec_tmout, + &afl->stop_soon) == 0) { + + bytes = count_bytes_len(afl, afl->taint_fsrv.trace_bits, plen); + if (afl->debug) + fprintf(stderr, "Debug: tainted %u out of %u bytes\n", bytes, len); + + if (bytes) { + + s32 i = len; + while (i > 0 && !afl->taint_fsrv.trace_bits[i - 1]) + i--; + q->taint_bytes_highest = i; + + } + + } + + if (((bytes * 100) / len) < 90) { + + // we only use the taint havoc mode if the entry has less than 90% of + // overall tainted bytes + q->taint_bytes_all = bytes; + + // save the bytes away + int w = open(q->fname_taint, O_CREAT | O_WRONLY, 0644); + if (w >= 0) { + + ck_write(w, afl->taint_fsrv.trace_bits, plen, q->fname_taint); + close(w); + + } else { + + FATAL("could not create %s", q->fname_taint); + bytes = 0; + + } + + if (bytes && prev && prev->taint_bytes_all) { + + // check if there are new bytes in the taint vs the previous + int r = open(prev->fname_taint, O_RDONLY); + + if (r >= 0) { + + u8 *bufr = mmap(0, prev->len, PROT_READ, MAP_PRIVATE, r, 0); + + if ((size_t)bufr != -1) { + + u32 i; + u8 *tmp = ck_maybe_grow(BUF_PARAMS(in_scratch), plen); + memset(tmp, 0, plen); + + for (i = 0; i < len; i++) + if (afl->taint_fsrv.trace_bits[i] && (i >= prev->len || !bufr[i])) + tmp[i] = 1; + + q->taint_bytes_new = count_bytes_len(afl, tmp, plen); + + if (q->taint_bytes_new) { + + u8 *fnw = alloc_printf("%s.new", q->fname_taint); + int w = open(fnw, O_CREAT | O_WRONLY, 0644); + if (w >= 0) { + + ck_write(w, tmp, plen, fnw); + close(w); + + } else { + + q->taint_bytes_new = 0; + + } + + ck_free(fnw); + + } + + munmap(bufr, prev->len); + + } + + close(r); + + } + + } + + } else { + + bytes = 0; + + } + + } + + if (!bytes) { + + q->taint_bytes_highest = q->taint_bytes_all = q->taint_bytes_new = 0; + + if (q->fname_taint) { + + ck_free(q->fname_taint); + q->fname_taint = NULL; + + } + + } else { + + if (q->taint_bytes_all && !q->taint_bytes_new) + q->taint_bytes_new = q->taint_bytes_all; + + } + +} + /* check if ascii or UTF-8 */ static u8 check_if_text(struct queue_entry *q) { @@ -212,10 +345,12 @@ static u8 check_if_text(struct queue_entry *q) { /* Append new test case to the queue. */ -void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { +void add_to_queue(afl_state_t *afl, u8 *fname, u8 *mem, u32 len, + struct queue_entry *prev_q, u8 passed_det) { struct queue_entry *q = ck_alloc(sizeof(struct queue_entry)); + q->prev = prev_q; q->fname = fname; q->len = len; q->depth = afl->cur_depth + 1; @@ -254,6 +389,17 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { afl->last_path_time = get_cur_time(); + /* trigger the tain gathering if this is not a dry run */ + if (afl->fsrv.taint_mode && mem) { + + perform_taint_run(afl, q, fname, mem, len); + + } + + /* only redqueen currently uses is_ascii */ + if (afl->shm.cmplog_mode) q->is_ascii = check_if_text(q); + + /* run custom mutators afl_custom_queue_new_entry() */ if (afl->custom_mutators_count) { LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { @@ -273,9 +419,6 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { } - /* only redqueen currently uses is_ascii */ - if (afl->shm.cmplog_mode) q->is_ascii = check_if_text(q); - } /* Destroy the entire queue. */ diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 89ae0424..ddbd5524 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -471,24 +471,6 @@ abort_calibration: afl->stage_cur = old_sc; afl->stage_max = old_sm; - /* if taint mode was selected, run the taint */ - - if (afl->fsrv.taint_mode) { - - write_to_testcase(afl, use_mem, q->len); - if (afl_fsrv_run_target(&afl->taint_fsrv, use_tmout, &afl->stop_soon) == - 0) { - - u32 len = q->len; - if (len % 4) len = len + 4 - (q->len % 4); - u32 bytes = count_bytes_len(afl, afl->taint_fsrv.trace_bits, len); - if (afl->debug) - fprintf(stderr, "Debug: tainted %u out of %u bytes\n", bytes, q->len); - - } - - } - if (!first_run) { show_stats(afl); } return fault; @@ -770,56 +752,65 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { while (remove_pos < q->len) { u32 trim_avail = MIN(remove_len, q->len - remove_pos); - u64 cksum; - write_with_gap(afl, in_buf, q->len, remove_pos, trim_avail); + if (likely((!q->taint_bytes_highest) || + (q->len - trim_avail > q->taint_bytes_highest))) { - fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); - ++afl->trim_execs; + u64 cksum; - if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; } + write_with_gap(afl, in_buf, q->len, remove_pos, trim_avail); - /* Note that we don't keep track of crashes or hangs here; maybe TODO? - */ + fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); + ++afl->trim_execs; - cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); + if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; } - /* If the deletion had no impact on the trace, make it permanent. This - isn't perfect for variable-path inputs, but we're just making a - best-effort pass, so it's not a big deal if we end up with false - negatives every now and then. */ + /* Note that we don't keep track of crashes or hangs here; maybe TODO? + */ - if (cksum == q->exec_cksum) { + cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); - u32 move_tail = q->len - remove_pos - trim_avail; + /* If the deletion had no impact on the trace, make it permanent. This + isn't perfect for variable-path inputs, but we're just making a + best-effort pass, so it's not a big deal if we end up with false + negatives every now and then. */ - q->len -= trim_avail; - len_p2 = next_pow2(q->len); + if (cksum == q->exec_cksum) { - memmove(in_buf + remove_pos, in_buf + remove_pos + trim_avail, - move_tail); + u32 move_tail = q->len - remove_pos - trim_avail; - /* Let's save a clean trace, which will be needed by - update_bitmap_score once we're done with the trimming stuff. */ + q->len -= trim_avail; + len_p2 = next_pow2(q->len); - if (!needs_write) { + memmove(in_buf + remove_pos, in_buf + remove_pos + trim_avail, + move_tail); - needs_write = 1; - memcpy(afl->clean_trace, afl->fsrv.trace_bits, afl->fsrv.map_size); + /* Let's save a clean trace, which will be needed by + update_bitmap_score once we're done with the trimming stuff. */ + + if (!needs_write) { + + needs_write = 1; + memcpy(afl->clean_trace, afl->fsrv.trace_bits, afl->fsrv.map_size); + + } + + } else { + + remove_pos += remove_len; } + /* Since this can be slow, update the screen every now and then. */ + if (!(trim_exec++ % afl->stats_update_freq)) { show_stats(afl); } + ++afl->stage_cur; + } else { remove_pos += remove_len; } - /* Since this can be slow, update the screen every now and then. */ - - if (!(trim_exec++ % afl->stats_update_freq)) { show_stats(afl); } - ++afl->stage_cur; - } remove_len >>= 1; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 93ab90e2..6f143db7 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -244,9 +244,10 @@ static int stricmp(char const *a, char const *b) { int main(int argc, char **argv_orig, char **envp) { - s32 opt; - u64 prev_queued = 0; - u32 sync_interval_cnt = 0, seek_to, show_help = 0, map_size = MAP_SIZE; + s32 opt; + u64 prev_queued = 0; + u32 sync_interval_cnt = 0, seek_to, show_help = 0, map_size = MAP_SIZE, + real_map_size = 0; u8 * extras_dir = 0; u8 mem_limit_given = 0, exit_1 = 0, debug = 0; char **use_argv; @@ -827,6 +828,7 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->fsrv.taint_mode && afl->fsrv.map_size < MAX_FILE) { + real_map_size = map_size; map_size = afl->fsrv.map_size = afl->shm.map_size = MAX_FILE; } @@ -840,8 +842,7 @@ int main(int argc, char **argv_orig, char **envp) { OKF("afl++ is open source, get it at " "https://github.com/AFLplusplus/AFLplusplus"); OKF("Power schedules from github.com/mboehme/aflfast"); - OKF("Python Mutator and llvm_mode instrument file list from " - "github.com/choller/afl"); + OKF("Python Mutator from github.com/choller/afl"); OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL"); if (afl->sync_id && afl->is_main_node && @@ -1088,6 +1089,13 @@ int main(int argc, char **argv_orig, char **envp) { memset(afl->virgin_tmout, 255, afl->fsrv.map_size); memset(afl->virgin_crash, 255, afl->fsrv.map_size); + if (map_size != real_map_size) { + + afl->fsrv.map_size = real_map_size; + if (afl->cmplog_binary) afl->cmplog_fsrv.map_size; + + } + init_count_class16(); if (afl->is_main_node && check_main_node_exists(afl) == 1) { @@ -1252,12 +1260,16 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->fsrv.taint_mode) { ACTF("Spawning qemu_taint forkserver"); + u8 *disable = getenv("AFL_DISABLE_LLVM_INSTRUMENTATION"); + setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); afl_fsrv_init_dup(&afl->taint_fsrv, &afl->fsrv); afl->taint_fsrv.qemu_mode = 2; + afl->taint_fsrv.taint_mode = 1; afl->taint_fsrv.trace_bits = afl->fsrv.trace_bits; ck_free(afl->taint_fsrv.target_path); - afl->taint_fsrv.target_path = ck_strdup(afl->fsrv.target_path); afl->argv_taint = ck_alloc(sizeof(char *) * (argc + 4 - optind)); + afl->taint_fsrv.target_path = + find_binary_own_loc("afl-qemu-taint", argv[0]); afl->argv_taint[0] = find_binary_own_loc("afl-qemu-taint", argv[0]); if (!afl->argv_taint[0]) FATAL( @@ -1278,6 +1290,7 @@ int main(int argc, char **argv_orig, char **envp) { setenv("AFL_TAINT_INPUT", afl->fsrv.out_file, 1); afl_fsrv_start(&afl->taint_fsrv, afl->argv_taint, &afl->stop_soon, afl->afl_env.afl_debug_child_output); + if (!disable) unsetenv("AFL_DISABLE_LLVM_INSTRUMENTATION"); OKF("Taint forkserver successfully started"); } -- cgit v1.2.3 From e99d7e973001adea65c68113b08792144d6aa5c8 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 9 Aug 2020 20:24:56 +0200 Subject: integration in fuzz_one --- src/afl-fuzz-one.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++------- src/afl-fuzz-run.c | 25 ++++++++++++ src/afl-fuzz.c | 12 ++++++ 3 files changed, 135 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 74e09ee3..ec7c4772 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -458,27 +458,102 @@ u8 fuzz_one_original(afl_state_t *afl) { } - /* Map the test case into memory. */ + if (unlikely(afl->fsrv.taint_mode && (afl->queue_cycle % 3))) { - fd = open(afl->queue_cur->fname, O_RDONLY); + if (unlikely(afl->queue_cur->cal_failed)) goto abandon_entry; - if (unlikely(fd < 0)) { + u32 dst = 0, i; - PFATAL("Unable to open '%s'", afl->queue_cur->fname); + fd = open(afl->queue_cur->fname, O_RDONLY); + afl->taint_src = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + if (fd < 0 || (size_t)afl->taint_src == -1) + FATAL("unable to open '%s'", afl->queue_cur->fname); + close(fd); - } + switch (afl->queue_cycle % 3) { - len = afl->queue_cur->len; + case 0: // do nothing, but cannot happen -> else + break; - orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + case 1: // fuzz only tainted bytes + if (!afl->queue_cur->taint_bytes_all) goto abandon_entry; + afl->taint_needs_splode = 1; - if (unlikely(orig_in == MAP_FAILED)) { + fd = open(afl->taint_input_file, O_RDONLY); + len = afl->taint_len = afl->queue_cur->taint_bytes_all; + orig_in = in_buf = + mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + if (fd < 0 || (size_t)in_buf == -1) + FATAL("unable to open '%s'", afl->taint_input_file); + close(fd); - PFATAL("Unable to mmap '%s' with len %d", afl->queue_cur->fname, len); + fd = open(afl->queue_cur->fname_taint, O_RDWR); + afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE, + MAP_PRIVATE, fd, 0); + if (fd < 0 || (size_t)in_buf == -1) + FATAL("unable to open '%s'", afl->queue_cur->fname_taint); + close(fd); - } + for (i = 0; i < afl->queue_cur->len && dst < len; i++) + if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i]; - close(fd); + break; + + case 2: // fuzz only newly tainted bytes + if (!afl->queue_cur->taint_bytes_new) goto abandon_entry; + afl->taint_needs_splode = 1; + + fd = open(afl->taint_input_file, O_RDONLY); + len = afl->taint_len = afl->queue_cur->taint_bytes_new; + orig_in = in_buf = + mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + if (fd < 0 || (size_t)in_buf == -1) + FATAL("unable to open '%s'", afl->taint_input_file); + close(fd); + + u8 *fn = alloc_printf("%s.new", afl->queue_cur->fname_taint); + fd = open(fn, O_RDWR); + afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE, + MAP_PRIVATE, fd, 0); + if (fd < 0 || (size_t)in_buf == -1) FATAL("unable to open '%s'", fn); + close(fd); + ck_free(fn); + + for (i = 0; i < afl->queue_cur->len && dst < len; i++) + if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i]; + + break; + + } + + goto havoc_stage; // we let the normal cycles do deterministic mode - if + + } else { + + /* Map the test case into memory. */ + afl->taint_needs_splode = 0; + + fd = open(afl->queue_cur->fname, O_RDONLY); + + if (unlikely(fd < 0)) { + + PFATAL("Unable to open '%s'", afl->queue_cur->fname); + + } + + len = afl->queue_cur->len; + + orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + + if (unlikely(orig_in == MAP_FAILED)) { + + PFATAL("Unable to mmap '%s' with len %d", afl->queue_cur->fname, len); + + } + + close(fd); + + } /* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every single byte anyway, so it wouldn't give us any performance or memory usage @@ -527,7 +602,7 @@ u8 fuzz_one_original(afl_state_t *afl) { ************/ if (!afl->non_instrumented_mode && !afl->queue_cur->trim_done && - !afl->disable_trim) { + !afl->disable_trim && !afl->taint_needs_splode) { u8 res = trim_case(afl, afl->queue_cur, in_buf); @@ -2568,7 +2643,17 @@ abandon_entry: ++afl->queue_cur->fuzz_level; - munmap(orig_in, afl->queue_cur->len); + if (afl->taint_needs_splode) { + + munmap(afl->taint_src, afl->queue_cur->len); + munmap(orig_in, afl->taint_len); + munmap(afl->taint_map, afl->queue_cur->len); + + } else { + + munmap(orig_in, afl->queue_cur->len); + + } return ret_val; diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index ddbd5524..31db4d7c 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -863,6 +863,8 @@ abort_trimming: } +#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size + /* Write a modified test case, run program, process results. Handle error conditions, returning 1 if it's time to bail out. This is a helper function for fuzz_one(). */ @@ -871,6 +873,27 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { u8 fault; + if (unlikely(afl->taint_needs_splode)) { + + s32 new_len = afl->queue_cur->len + len - afl->taint_len; + if (new_len < 4) new_len = 4; + u8 *new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), new_len); + + u32 i, taint = 0; + for (i = 0; i < new_len; i++) { + + if (afl->taint_map[i] || i > afl->queue_cur->len) + new_buf[i] = out_buf[taint++]; + else + new_buf[i] = afl->taint_src[i]; + + } + + out_buf = new_buf; + len = new_len; + + } + write_to_testcase(afl, out_buf, len); fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); @@ -918,3 +941,5 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { } +#undef BUF_PARAMS + diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 6f143db7..70a99dec 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1260,12 +1260,15 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->fsrv.taint_mode) { ACTF("Spawning qemu_taint forkserver"); + u8 *disable = getenv("AFL_DISABLE_LLVM_INSTRUMENTATION"); setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); + afl_fsrv_init_dup(&afl->taint_fsrv, &afl->fsrv); afl->taint_fsrv.qemu_mode = 2; afl->taint_fsrv.taint_mode = 1; afl->taint_fsrv.trace_bits = afl->fsrv.trace_bits; + ck_free(afl->taint_fsrv.target_path); afl->argv_taint = ck_alloc(sizeof(char *) * (argc + 4 - optind)); afl->taint_fsrv.target_path = @@ -1290,7 +1293,16 @@ int main(int argc, char **argv_orig, char **envp) { setenv("AFL_TAINT_INPUT", afl->fsrv.out_file, 1); afl_fsrv_start(&afl->taint_fsrv, afl->argv_taint, &afl->stop_soon, afl->afl_env.afl_debug_child_output); + + afl->taint_input_file = alloc_printf("%s/taint/.input", afl->out_dir); + int fd = open(afl->taint_input_file, O_CREAT | O_TRUNC | O_RDWR, 0644); + if (fd < 0) + FATAL("Cannot create taint inpu file '%s'", afl->taint_input_file); + lseek(fd, MAX_FILE, SEEK_SET); + ck_write(fd, "\0", 1, afl->taint_input_file); + if (!disable) unsetenv("AFL_DISABLE_LLVM_INSTRUMENTATION"); + OKF("Taint forkserver successfully started"); } -- cgit v1.2.3 From ff40359a608f3c14c1025908a2810ca71fd502af Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 9 Aug 2020 21:09:07 +0200 Subject: fixes --- src/afl-fuzz-init.c | 8 +++++++- src/afl-fuzz-one.c | 28 ++++++++++++++++------------ src/afl-fuzz-queue.c | 10 +++++----- 3 files changed, 28 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 350a3b4c..432e0649 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -961,7 +961,8 @@ void perform_dry_run(afl_state_t *afl) { } /* perform taint gathering on the input seed */ - perform_taint_run(afl, q, q->fname, use_mem, q->len); + if (afl->fsrv.taint_mode) + perform_taint_run(afl, q, q->fname, use_mem, q->len); q = q->next; @@ -1505,6 +1506,11 @@ static void handle_existing_out_dir(afl_state_t *afl) { fn = alloc_printf("%s/taint", afl->out_dir); mkdir(fn, 0755); // ignore errors + + u8 *fn2 = alloc_printf("%s/taint/.input", afl->out_dir); + unlink(fn2); // ignore errors + ck_free(fn2); + if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index ec7c4772..e75c2cec 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -458,26 +458,31 @@ u8 fuzz_one_original(afl_state_t *afl) { } - if (unlikely(afl->fsrv.taint_mode && (afl->queue_cycle % 3))) { + u32 tmp_val; + + if (unlikely(afl->fsrv.taint_mode && + (tmp_val = (afl->queue_cycle % 3)) != 1)) { if (unlikely(afl->queue_cur->cal_failed)) goto abandon_entry; + if (tmp_val == 1 && !afl->queue_cur->taint_bytes_all) goto abandon_entry; + if (tmp_val == 2 && !afl->queue_cur->taint_bytes_new) goto abandon_entry; u32 dst = 0, i; + temp_len = len = afl->queue_cur->len; fd = open(afl->queue_cur->fname, O_RDONLY); afl->taint_src = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (fd < 0 || (size_t)afl->taint_src == -1) FATAL("unable to open '%s'", afl->queue_cur->fname); close(fd); + afl->taint_needs_splode = 1; - switch (afl->queue_cycle % 3) { + switch (tmp_val) { - case 0: // do nothing, but cannot happen -> else + case 1: // do nothing, but cannot happen -> else break; - case 1: // fuzz only tainted bytes - if (!afl->queue_cur->taint_bytes_all) goto abandon_entry; - afl->taint_needs_splode = 1; + case 2: // fuzz only tainted bytes fd = open(afl->taint_input_file, O_RDONLY); len = afl->taint_len = afl->queue_cur->taint_bytes_all; @@ -499,9 +504,7 @@ u8 fuzz_one_original(afl_state_t *afl) { break; - case 2: // fuzz only newly tainted bytes - if (!afl->queue_cur->taint_bytes_new) goto abandon_entry; - afl->taint_needs_splode = 1; + case 0: // fuzz only newly tainted bytes fd = open(afl->taint_input_file, O_RDONLY); len = afl->taint_len = afl->queue_cur->taint_bytes_new; @@ -515,7 +518,8 @@ u8 fuzz_one_original(afl_state_t *afl) { fd = open(fn, O_RDWR); afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (fd < 0 || (size_t)in_buf == -1) FATAL("unable to open '%s'", fn); + if (fd < 0 || (size_t)in_buf == -1) + FATAL("unable to open '%s' for %u bytes", fn, len); close(fd); ck_free(fn); @@ -526,8 +530,6 @@ u8 fuzz_one_original(afl_state_t *afl) { } - goto havoc_stage; // we let the normal cycles do deterministic mode - if - } else { /* Map the test case into memory. */ @@ -653,6 +655,8 @@ u8 fuzz_one_original(afl_state_t *afl) { if it has gone through deterministic testing in earlier, resumed runs (passed_det). */ + if (afl->taint_needs_splode) goto havoc_stage; + if (likely(afl->queue_cur->passed_det) || likely(afl->skip_deterministic) || likely(perf_score < (afl->queue_cur->depth * 30 <= afl->havoc_max_mult * 100 diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 36ec0896..3ada9d98 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -118,6 +118,9 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname, if (q->fname_taint) { + u8 *save = ck_maybe_grow(BUF_PARAMS(out_scratch), afl->fsrv.map_size); + memcpy(save, afl->taint_fsrv.trace_bits, afl->fsrv.map_size); + afl->taint_fsrv.map_size = plen; // speed :) write_to_testcase(afl, mem, len); if (afl_fsrv_run_target(&afl->taint_fsrv, afl->fsrv.exec_tmout, @@ -214,6 +217,8 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname, } + memcpy(afl->taint_fsrv.trace_bits, save, afl->fsrv.map_size); + } if (!bytes) { @@ -227,11 +232,6 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname, } - } else { - - if (q->taint_bytes_all && !q->taint_bytes_new) - q->taint_bytes_new = q->taint_bytes_all; - } } -- cgit v1.2.3 From 4fc16b542e7839698f91dca46db52044fdaa9dd2 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 9 Aug 2020 21:32:15 +0200 Subject: havoc copy --- src/afl-fuzz-one.c | 762 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 761 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index e75c2cec..5dc336dc 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -463,10 +463,14 @@ u8 fuzz_one_original(afl_state_t *afl) { if (unlikely(afl->fsrv.taint_mode && (tmp_val = (afl->queue_cycle % 3)) != 1)) { + ret_val = 0; + if (unlikely(afl->queue_cur->cal_failed)) goto abandon_entry; if (tmp_val == 1 && !afl->queue_cur->taint_bytes_all) goto abandon_entry; if (tmp_val == 2 && !afl->queue_cur->taint_bytes_new) goto abandon_entry; + ret_val = 1; + u32 dst = 0, i; temp_len = len = afl->queue_cur->len; @@ -655,7 +659,7 @@ u8 fuzz_one_original(afl_state_t *afl) { if it has gone through deterministic testing in earlier, resumed runs (passed_det). */ - if (afl->taint_needs_splode) goto havoc_stage; + if (afl->taint_needs_splode) goto taint_havoc_stage; if (likely(afl->queue_cur->passed_det) || likely(afl->skip_deterministic) || likely(perf_score < @@ -2628,6 +2632,762 @@ retry_splicing: ret_val = 0; + goto abandon_entry; + + /******************************* + * same RANDOM HAVOC for taint * + *******************************/ + +taint_havoc_stage: + + afl->stage_cur_byte = -1; + + /* The havoc stage mutation code is also invoked when splicing files; if the + splice_cycle variable is set, generate different descriptions and such. */ + + if (!splice_cycle) { + + afl->stage_name = "havoc"; + afl->stage_short = "havoc"; + afl->stage_max = (doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) * + perf_score / afl->havoc_div / 100; + + } else { + + perf_score = orig_perf; + + snprintf(afl->stage_name_buf, STAGE_BUF_SIZE, "splice %u", splice_cycle); + afl->stage_name = afl->stage_name_buf; + afl->stage_short = "splice"; + afl->stage_max = SPLICE_HAVOC * perf_score / afl->havoc_div / 100; + + } + + if (afl->stage_max < HAVOC_MIN) { afl->stage_max = HAVOC_MIN; } + + temp_len = len; + + orig_hit_cnt = afl->queued_paths + afl->unique_crashes; + + havoc_queued = afl->queued_paths; + + if (afl->custom_mutators_count) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->stacked_custom && el->afl_custom_havoc_mutation_probability) { + + el->stacked_custom_prob = + el->afl_custom_havoc_mutation_probability(el->data); + if (el->stacked_custom_prob > 100) { + + FATAL( + "The probability returned by " + "afl_custom_havoc_mutation_propability " + "has to be in the range 0-100."); + + } + + } + + }); + + } + + /* We essentially just do several thousand runs (depending on perf_score) + where we take the input file and make random stacked tweaks. */ + + if (unlikely(afl->expand_havoc)) { + + /* add expensive havoc cases here, they are activated after a full + cycle without finds happened */ + + r_max = 16 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0); + + } else { + + r_max = 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0); + + } + + for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { + + u32 use_stacking = 1 << (1 + rand_below(afl, HAVOC_STACK_POW2)); + + afl->stage_cur_val = use_stacking; + + for (i = 0; i < use_stacking; ++i) { + + if (afl->custom_mutators_count) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->stacked_custom && + rand_below(afl, 100) < el->stacked_custom_prob) { + + u8 * custom_havoc_buf = NULL; + size_t new_len = el->afl_custom_havoc_mutation( + el->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE); + if (unlikely(!custom_havoc_buf)) { + + FATAL("Error in custom_havoc (return %zd)", new_len); + + } + + if (likely(new_len > 0 && custom_havoc_buf)) { + + temp_len = new_len; + if (out_buf != custom_havoc_buf) { + + ck_maybe_grow(BUF_PARAMS(out), temp_len); + memcpy(out_buf, custom_havoc_buf, temp_len); + + } + + } + + } + + }); + + } + + switch ((r = rand_below(afl, r_max))) { + + case 0: + + /* Flip a single bit somewhere. Spooky! */ + + FLIP_BIT(out_buf, rand_below(afl, temp_len << 3)); + break; + + case 1: + + /* Set byte to interesting value. */ + + out_buf[rand_below(afl, temp_len)] = + interesting_8[rand_below(afl, sizeof(interesting_8))]; + break; + + case 2: + + /* Set word to interesting value, randomly choosing endian. */ + + if (temp_len < 2) { break; } + + if (rand_below(afl, 2)) { + + *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = + interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]; + + } else { + + *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = SWAP16( + interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]); + + } + + break; + + case 3: + + /* Set dword to interesting value, randomly choosing endian. */ + + if (temp_len < 4) { break; } + + if (rand_below(afl, 2)) { + + *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = + interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]; + + } else { + + *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = SWAP32( + interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]); + + } + + break; + + case 4: + + /* Randomly subtract from byte. */ + + out_buf[rand_below(afl, temp_len)] -= 1 + rand_below(afl, ARITH_MAX); + break; + + case 5: + + /* Randomly add to byte. */ + + out_buf[rand_below(afl, temp_len)] += 1 + rand_below(afl, ARITH_MAX); + break; + + case 6: + + /* Randomly subtract from word, random endian. */ + + if (temp_len < 2) { break; } + + if (rand_below(afl, 2)) { + + u32 pos = rand_below(afl, temp_len - 1); + + *(u16 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); + + } else { + + u32 pos = rand_below(afl, temp_len - 1); + u16 num = 1 + rand_below(afl, ARITH_MAX); + + *(u16 *)(out_buf + pos) = + SWAP16(SWAP16(*(u16 *)(out_buf + pos)) - num); + + } + + break; + + case 7: + + /* Randomly add to word, random endian. */ + + if (temp_len < 2) { break; } + + if (rand_below(afl, 2)) { + + u32 pos = rand_below(afl, temp_len - 1); + + *(u16 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); + + } else { + + u32 pos = rand_below(afl, temp_len - 1); + u16 num = 1 + rand_below(afl, ARITH_MAX); + + *(u16 *)(out_buf + pos) = + SWAP16(SWAP16(*(u16 *)(out_buf + pos)) + num); + + } + + break; + + case 8: + + /* Randomly subtract from dword, random endian. */ + + if (temp_len < 4) { break; } + + if (rand_below(afl, 2)) { + + u32 pos = rand_below(afl, temp_len - 3); + + *(u32 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); + + } else { + + u32 pos = rand_below(afl, temp_len - 3); + u32 num = 1 + rand_below(afl, ARITH_MAX); + + *(u32 *)(out_buf + pos) = + SWAP32(SWAP32(*(u32 *)(out_buf + pos)) - num); + + } + + break; + + case 9: + + /* Randomly add to dword, random endian. */ + + if (temp_len < 4) { break; } + + if (rand_below(afl, 2)) { + + u32 pos = rand_below(afl, temp_len - 3); + + *(u32 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); + + } else { + + u32 pos = rand_below(afl, temp_len - 3); + u32 num = 1 + rand_below(afl, ARITH_MAX); + + *(u32 *)(out_buf + pos) = + SWAP32(SWAP32(*(u32 *)(out_buf + pos)) + num); + + } + + break; + + case 10: + + /* Just set a random byte to a random value. Because, + why not. We use XOR with 1-255 to eliminate the + possibility of a no-op. */ + + out_buf[rand_below(afl, temp_len)] ^= 1 + rand_below(afl, 255); + break; + + case 11 ... 12: { + + /* Delete bytes. We're making this a bit more likely + than insertion (the next option) in hopes of keeping + files reasonably small. */ + + u32 del_from, del_len; + + if (temp_len < 2) { break; } + + /* Don't delete too much. */ + + del_len = choose_block_len(afl, temp_len - 1); + + del_from = rand_below(afl, temp_len - del_len + 1); + + memmove(out_buf + del_from, out_buf + del_from + del_len, + temp_len - del_from - del_len); + + temp_len -= del_len; + + break; + + } + + case 13: + + if (temp_len + HAVOC_BLK_XL < MAX_FILE) { + + /* Clone bytes (75%) or insert a block of constant bytes (25%). */ + + u8 actually_clone = rand_below(afl, 4); + u32 clone_from, clone_to, clone_len; + u8 *new_buf; + + if (actually_clone) { + + clone_len = choose_block_len(afl, temp_len); + clone_from = rand_below(afl, temp_len - clone_len + 1); + + } else { + + clone_len = choose_block_len(afl, HAVOC_BLK_XL); + clone_from = 0; + + } + + clone_to = rand_below(afl, temp_len); + + new_buf = + ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); + + /* Head */ + + memcpy(new_buf, out_buf, clone_to); + + /* Inserted part */ + + if (actually_clone) { + + memcpy(new_buf + clone_to, out_buf + clone_from, clone_len); + + } else { + + memset(new_buf + clone_to, + rand_below(afl, 2) ? rand_below(afl, 256) + : out_buf[rand_below(afl, temp_len)], + clone_len); + + } + + /* Tail */ + memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, + temp_len - clone_to); + + swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); + out_buf = new_buf; + new_buf = NULL; + temp_len += clone_len; + + } + + break; + + case 14: { + + /* Overwrite bytes with a randomly selected chunk (75%) or fixed + bytes (25%). */ + + u32 copy_from, copy_to, copy_len; + + if (temp_len < 2) { break; } + + copy_len = choose_block_len(afl, temp_len - 1); + + copy_from = rand_below(afl, temp_len - copy_len + 1); + copy_to = rand_below(afl, temp_len - copy_len + 1); + + if (rand_below(afl, 4)) { + + if (copy_from != copy_to) { + + memmove(out_buf + copy_to, out_buf + copy_from, copy_len); + + } + + } else { + + memset(out_buf + copy_to, + rand_below(afl, 2) ? rand_below(afl, 256) + : out_buf[rand_below(afl, temp_len)], + copy_len); + + } + + break; + + } + + default: + + if (likely(r <= 16 && (afl->extras_cnt || afl->a_extras_cnt))) { + + /* Values 15 and 16 can be selected only if there are any extras + present in the dictionaries. */ + + if (r == 15) { + + /* Overwrite bytes with an extra. */ + + if (!afl->extras_cnt || + (afl->a_extras_cnt && rand_below(afl, 2))) { + + /* No user-specified extras or odds in our favor. Let's use an + auto-detected one. */ + + u32 use_extra = rand_below(afl, afl->a_extras_cnt); + u32 extra_len = afl->a_extras[use_extra].len; + u32 insert_at; + + if ((s32)extra_len > temp_len) { break; } + + insert_at = rand_below(afl, temp_len - extra_len + 1); + memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, + extra_len); + + } else { + + /* No auto extras or odds in our favor. Use the dictionary. */ + + u32 use_extra = rand_below(afl, afl->extras_cnt); + u32 extra_len = afl->extras[use_extra].len; + u32 insert_at; + + if ((s32)extra_len > temp_len) { break; } + + insert_at = rand_below(afl, temp_len - extra_len + 1); + memcpy(out_buf + insert_at, afl->extras[use_extra].data, + extra_len); + + } + + break; + + } else { // case 16 + + u32 use_extra, extra_len, + insert_at = rand_below(afl, temp_len + 1); + u8 *ptr; + + /* Insert an extra. Do the same dice-rolling stuff as for the + previous case. */ + + if (!afl->extras_cnt || + (afl->a_extras_cnt && rand_below(afl, 2))) { + + use_extra = rand_below(afl, afl->a_extras_cnt); + extra_len = afl->a_extras[use_extra].len; + ptr = afl->a_extras[use_extra].data; + + } else { + + use_extra = rand_below(afl, afl->extras_cnt); + extra_len = afl->extras[use_extra].len; + ptr = afl->extras[use_extra].data; + + } + + if (temp_len + extra_len >= MAX_FILE) { break; } + + out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len); + + /* Tail */ + memmove(out_buf + insert_at + extra_len, out_buf + insert_at, + temp_len - insert_at); + + /* Inserted part */ + memcpy(out_buf + insert_at, ptr, extra_len); + + temp_len += extra_len; + + break; + + } + + } else { + + /* + switch (r) { + + case 15: // fall through + case 16: + case 17: {*/ + + /* Overwrite bytes with a randomly selected chunk from another + testcase or insert that chunk. */ + + if (afl->queued_paths < 4) break; + + /* Pick a random queue entry and seek to it. */ + + u32 tid; + do + tid = rand_below(afl, afl->queued_paths); + while (tid == afl->current_entry); + + struct queue_entry *target = afl->queue_buf[tid]; + + /* Make sure that the target has a reasonable length. */ + + while (target && (target->len < 2 || target == afl->queue_cur)) + target = target->next; + + if (!target) break; + + /* Read the testcase into a new buffer. */ + + fd = open(target->fname, O_RDONLY); + + if (unlikely(fd < 0)) { + + PFATAL("Unable to open '%s'", target->fname); + + } + + u32 new_len = target->len; + u8 *new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), new_len); + + ck_read(fd, new_buf, new_len, target->fname); + + close(fd); + + u8 overwrite = 0; + if (temp_len >= 2 && rand_below(afl, 2)) + overwrite = 1; + else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { + + if (temp_len >= 2) + overwrite = 1; + else + break; + + } + + if (overwrite) { + + u32 copy_from, copy_to, copy_len; + + copy_len = choose_block_len(afl, new_len - 1); + if ((s32)copy_len > temp_len) copy_len = temp_len; + + copy_from = rand_below(afl, new_len - copy_len + 1); + copy_to = rand_below(afl, temp_len - copy_len + 1); + + memmove(out_buf + copy_to, new_buf + copy_from, copy_len); + + } else { + + u32 clone_from, clone_to, clone_len; + + clone_len = choose_block_len(afl, new_len); + clone_from = rand_below(afl, new_len - clone_len + 1); + + clone_to = rand_below(afl, temp_len); + + u8 *temp_buf = + ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); + + /* Head */ + + memcpy(temp_buf, out_buf, clone_to); + + /* Inserted part */ + + memcpy(temp_buf + clone_to, new_buf + clone_from, clone_len); + + /* Tail */ + memcpy(temp_buf + clone_to + clone_len, out_buf + clone_to, + temp_len - clone_to); + + swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); + out_buf = temp_buf; + temp_len += clone_len; + + } + + break; + + } + + // end of default: + + } + + } + + if (common_fuzz_stuff(afl, out_buf, temp_len)) { goto abandon_entry; } + + /* out_buf might have been mangled a bit, so let's restore it to its + original size and shape. */ + + out_buf = ck_maybe_grow(BUF_PARAMS(out), len); + temp_len = len; + memcpy(out_buf, in_buf, len); + + /* If we're finding new stuff, let's run for a bit longer, limits + permitting. */ + + if (afl->queued_paths != havoc_queued) { + + if (perf_score <= afl->havoc_max_mult * 100) { + + afl->stage_max *= 2; + perf_score *= 2; + + } + + havoc_queued = afl->queued_paths; + + } + + } + + new_hit_cnt = afl->queued_paths + afl->unique_crashes; + + if (!splice_cycle) { + + afl->stage_finds[STAGE_HAVOC] += new_hit_cnt - orig_hit_cnt; + afl->stage_cycles[STAGE_HAVOC] += afl->stage_max; + + } else { + + afl->stage_finds[STAGE_SPLICE] += new_hit_cnt - orig_hit_cnt; + afl->stage_cycles[STAGE_SPLICE] += afl->stage_max; + + } + +#ifndef IGNORE_FINDS + + /************ + * SPLICING * + ************/ + + /* This is a last-resort strategy triggered by a full round with no findings. + It takes the current input file, randomly selects another input, and + splices them together at some offset, then relies on the havoc + code to mutate that blob. */ + +taint_retry_splicing: + + if (afl->use_splicing && splice_cycle++ < SPLICE_CYCLES && + afl->queued_paths > 1 && afl->queue_cur->len > 1) { + + struct queue_entry *target; + u32 tid, split_at; + u8 * new_buf; + s32 f_diff, l_diff; + + /* First of all, if we've modified in_buf for havoc, let's clean that + up... */ + + if (in_buf != orig_in) { + + in_buf = orig_in; + len = afl->queue_cur->len; + + } + + /* Pick a random queue entry and seek to it. Don't splice with yourself. */ + + do { + + tid = rand_below(afl, afl->queued_paths); + + } while (tid == afl->current_entry); + + afl->splicing_with = tid; + target = afl->queue_buf[tid]; + + /* Make sure that the target has a reasonable length. */ + + while (target && (target->len < 2 || target == afl->queue_cur)) { + + target = target->next; + ++afl->splicing_with; + + } + + if (!target) { goto taint_retry_splicing; } + + /* Read the testcase into a new buffer. */ + + fd = open(target->fname, O_RDONLY); + + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); } + + new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), target->len); + + ck_read(fd, new_buf, target->len, target->fname); + + close(fd); + + /* Find a suitable splicing location, somewhere between the first and + the last differing byte. Bail out if the difference is just a single + byte or so. */ + + locate_diffs(in_buf, new_buf, MIN(len, (s64)target->len), &f_diff, &l_diff); + + if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { goto taint_retry_splicing; } + + /* Split somewhere between the first and last differing byte. */ + + split_at = f_diff + rand_below(afl, l_diff - f_diff); + + /* Do the thing. */ + + len = target->len; + memcpy(new_buf, in_buf, split_at); + swap_bufs(BUF_PARAMS(in), BUF_PARAMS(in_scratch)); + in_buf = new_buf; + + out_buf = ck_maybe_grow(BUF_PARAMS(out), len); + memcpy(out_buf, in_buf, len); + + goto custom_mutator_stage; + /* ???: While integrating Python module, the author decided to jump to + python stage, but the reason behind this is not clear.*/ + // goto havoc_stage; + + } + +#endif /* !IGNORE_FINDS */ + + + + ret_val = 0; + + goto abandon_entry; + + /* we are through with this queue entry - for this iteration */ abandon_entry: -- cgit v1.2.3 From 558a82891abb7617eb51d49991a128fccdc9be6e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 9 Aug 2020 22:02:44 +0200 Subject: finalize havoc --- src/afl-fuzz-one.c | 807 +++-------------------------------------------------- 1 file changed, 44 insertions(+), 763 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 5dc336dc..75381db8 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -489,7 +489,7 @@ u8 fuzz_one_original(afl_state_t *afl) { case 2: // fuzz only tainted bytes fd = open(afl->taint_input_file, O_RDONLY); - len = afl->taint_len = afl->queue_cur->taint_bytes_all; + temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_all; orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (fd < 0 || (size_t)in_buf == -1) @@ -511,7 +511,7 @@ u8 fuzz_one_original(afl_state_t *afl) { case 0: // fuzz only newly tainted bytes fd = open(afl->taint_input_file, O_RDONLY); - len = afl->taint_len = afl->queue_cur->taint_bytes_new; + temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_new; orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (fd < 0 || (size_t)in_buf == -1) @@ -659,7 +659,8 @@ u8 fuzz_one_original(afl_state_t *afl) { if it has gone through deterministic testing in earlier, resumed runs (passed_det). */ - if (afl->taint_needs_splode) goto taint_havoc_stage; + // custom mutators would not work, deterministic is done -> so havoc! + if (afl->taint_needs_splode) goto havoc_stage; if (likely(afl->queue_cur->passed_det) || likely(afl->skip_deterministic) || likely(perf_score < @@ -2214,760 +2215,19 @@ havoc_stage: if (actually_clone) { - clone_len = choose_block_len(afl, temp_len); - clone_from = rand_below(afl, temp_len - clone_len + 1); + if (unlikely(afl->taint_needs_splode)) { - } else { - - clone_len = choose_block_len(afl, HAVOC_BLK_XL); - clone_from = 0; - - } - - clone_to = rand_below(afl, temp_len); - - new_buf = - ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); - - /* Head */ - - memcpy(new_buf, out_buf, clone_to); - - /* Inserted part */ - - if (actually_clone) { - - memcpy(new_buf + clone_to, out_buf + clone_from, clone_len); - - } else { - - memset(new_buf + clone_to, - rand_below(afl, 2) ? rand_below(afl, 256) - : out_buf[rand_below(afl, temp_len)], - clone_len); - - } - - /* Tail */ - memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, - temp_len - clone_to); - - swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); - out_buf = new_buf; - new_buf = NULL; - temp_len += clone_len; - - } - - break; - - case 14: { - - /* Overwrite bytes with a randomly selected chunk (75%) or fixed - bytes (25%). */ - - u32 copy_from, copy_to, copy_len; - - if (temp_len < 2) { break; } - - copy_len = choose_block_len(afl, temp_len - 1); - - copy_from = rand_below(afl, temp_len - copy_len + 1); - copy_to = rand_below(afl, temp_len - copy_len + 1); - - if (rand_below(afl, 4)) { - - if (copy_from != copy_to) { - - memmove(out_buf + copy_to, out_buf + copy_from, copy_len); - - } - - } else { - - memset(out_buf + copy_to, - rand_below(afl, 2) ? rand_below(afl, 256) - : out_buf[rand_below(afl, temp_len)], - copy_len); - - } - - break; - - } - - default: - - if (likely(r <= 16 && (afl->extras_cnt || afl->a_extras_cnt))) { - - /* Values 15 and 16 can be selected only if there are any extras - present in the dictionaries. */ - - if (r == 15) { - - /* Overwrite bytes with an extra. */ - - if (!afl->extras_cnt || - (afl->a_extras_cnt && rand_below(afl, 2))) { - - /* No user-specified extras or odds in our favor. Let's use an - auto-detected one. */ - - u32 use_extra = rand_below(afl, afl->a_extras_cnt); - u32 extra_len = afl->a_extras[use_extra].len; - u32 insert_at; - - if ((s32)extra_len > temp_len) { break; } - - insert_at = rand_below(afl, temp_len - extra_len + 1); - memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, - extra_len); - - } else { - - /* No auto extras or odds in our favor. Use the dictionary. */ - - u32 use_extra = rand_below(afl, afl->extras_cnt); - u32 extra_len = afl->extras[use_extra].len; - u32 insert_at; - - if ((s32)extra_len > temp_len) { break; } - - insert_at = rand_below(afl, temp_len - extra_len + 1); - memcpy(out_buf + insert_at, afl->extras[use_extra].data, - extra_len); - - } - - break; - - } else { // case 16 - - u32 use_extra, extra_len, - insert_at = rand_below(afl, temp_len + 1); - u8 *ptr; - - /* Insert an extra. Do the same dice-rolling stuff as for the - previous case. */ - - if (!afl->extras_cnt || - (afl->a_extras_cnt && rand_below(afl, 2))) { - - use_extra = rand_below(afl, afl->a_extras_cnt); - extra_len = afl->a_extras[use_extra].len; - ptr = afl->a_extras[use_extra].data; - - } else { - - use_extra = rand_below(afl, afl->extras_cnt); - extra_len = afl->extras[use_extra].len; - ptr = afl->extras[use_extra].data; - - } - - if (temp_len + extra_len >= MAX_FILE) { break; } - - out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len); - - /* Tail */ - memmove(out_buf + insert_at + extra_len, out_buf + insert_at, - temp_len - insert_at); - - /* Inserted part */ - memcpy(out_buf + insert_at, ptr, extra_len); - - temp_len += extra_len; - - break; - - } - - } else { - - /* - switch (r) { - - case 15: // fall through - case 16: - case 17: {*/ - - /* Overwrite bytes with a randomly selected chunk from another - testcase or insert that chunk. */ - - if (afl->queued_paths < 4) break; - - /* Pick a random queue entry and seek to it. */ - - u32 tid; - do - tid = rand_below(afl, afl->queued_paths); - while (tid == afl->current_entry); - - struct queue_entry *target = afl->queue_buf[tid]; - - /* Make sure that the target has a reasonable length. */ - - while (target && (target->len < 2 || target == afl->queue_cur)) - target = target->next; - - if (!target) break; - - /* Read the testcase into a new buffer. */ - - fd = open(target->fname, O_RDONLY); - - if (unlikely(fd < 0)) { - - PFATAL("Unable to open '%s'", target->fname); - - } - - u32 new_len = target->len; - u8 *new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), new_len); - - ck_read(fd, new_buf, new_len, target->fname); - - close(fd); - - u8 overwrite = 0; - if (temp_len >= 2 && rand_below(afl, 2)) - overwrite = 1; - else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { - - if (temp_len >= 2) - overwrite = 1; - else - break; - - } - - if (overwrite) { - - u32 copy_from, copy_to, copy_len; - - copy_len = choose_block_len(afl, new_len - 1); - if ((s32)copy_len > temp_len) copy_len = temp_len; - - copy_from = rand_below(afl, new_len - copy_len + 1); - copy_to = rand_below(afl, temp_len - copy_len + 1); - - memmove(out_buf + copy_to, new_buf + copy_from, copy_len); - - } else { - - u32 clone_from, clone_to, clone_len; - - clone_len = choose_block_len(afl, new_len); - clone_from = rand_below(afl, new_len - clone_len + 1); - - clone_to = rand_below(afl, temp_len); - - u8 *temp_buf = - ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); - - /* Head */ - - memcpy(temp_buf, out_buf, clone_to); - - /* Inserted part */ - - memcpy(temp_buf + clone_to, new_buf + clone_from, clone_len); - - /* Tail */ - memcpy(temp_buf + clone_to + clone_len, out_buf + clone_to, - temp_len - clone_to); - - swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); - out_buf = temp_buf; - temp_len += clone_len; - - } - - break; - - } - - // end of default: - - } - - } - - if (common_fuzz_stuff(afl, out_buf, temp_len)) { goto abandon_entry; } - - /* out_buf might have been mangled a bit, so let's restore it to its - original size and shape. */ - - out_buf = ck_maybe_grow(BUF_PARAMS(out), len); - temp_len = len; - memcpy(out_buf, in_buf, len); - - /* If we're finding new stuff, let's run for a bit longer, limits - permitting. */ - - if (afl->queued_paths != havoc_queued) { - - if (perf_score <= afl->havoc_max_mult * 100) { - - afl->stage_max *= 2; - perf_score *= 2; - - } - - havoc_queued = afl->queued_paths; - - } - - } - - new_hit_cnt = afl->queued_paths + afl->unique_crashes; - - if (!splice_cycle) { - - afl->stage_finds[STAGE_HAVOC] += new_hit_cnt - orig_hit_cnt; - afl->stage_cycles[STAGE_HAVOC] += afl->stage_max; - - } else { - - afl->stage_finds[STAGE_SPLICE] += new_hit_cnt - orig_hit_cnt; - afl->stage_cycles[STAGE_SPLICE] += afl->stage_max; - - } - -#ifndef IGNORE_FINDS - - /************ - * SPLICING * - ************/ - - /* This is a last-resort strategy triggered by a full round with no findings. - It takes the current input file, randomly selects another input, and - splices them together at some offset, then relies on the havoc - code to mutate that blob. */ - -retry_splicing: - - if (afl->use_splicing && splice_cycle++ < SPLICE_CYCLES && - afl->queued_paths > 1 && afl->queue_cur->len > 1) { - - struct queue_entry *target; - u32 tid, split_at; - u8 * new_buf; - s32 f_diff, l_diff; - - /* First of all, if we've modified in_buf for havoc, let's clean that - up... */ - - if (in_buf != orig_in) { - - in_buf = orig_in; - len = afl->queue_cur->len; - - } - - /* Pick a random queue entry and seek to it. Don't splice with yourself. */ - - do { - - tid = rand_below(afl, afl->queued_paths); - - } while (tid == afl->current_entry); - - afl->splicing_with = tid; - target = afl->queue_buf[tid]; - - /* Make sure that the target has a reasonable length. */ - - while (target && (target->len < 2 || target == afl->queue_cur)) { - - target = target->next; - ++afl->splicing_with; - - } - - if (!target) { goto retry_splicing; } - - /* Read the testcase into a new buffer. */ - - fd = open(target->fname, O_RDONLY); - - if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); } - - new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), target->len); - - ck_read(fd, new_buf, target->len, target->fname); - - close(fd); - - /* Find a suitable splicing location, somewhere between the first and - the last differing byte. Bail out if the difference is just a single - byte or so. */ - - locate_diffs(in_buf, new_buf, MIN(len, (s64)target->len), &f_diff, &l_diff); - - if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { goto retry_splicing; } - - /* Split somewhere between the first and last differing byte. */ - - split_at = f_diff + rand_below(afl, l_diff - f_diff); - - /* Do the thing. */ - - len = target->len; - memcpy(new_buf, in_buf, split_at); - swap_bufs(BUF_PARAMS(in), BUF_PARAMS(in_scratch)); - in_buf = new_buf; - - out_buf = ck_maybe_grow(BUF_PARAMS(out), len); - memcpy(out_buf, in_buf, len); - - goto custom_mutator_stage; - /* ???: While integrating Python module, the author decided to jump to - python stage, but the reason behind this is not clear.*/ - // goto havoc_stage; - - } - -#endif /* !IGNORE_FINDS */ - - ret_val = 0; - - goto abandon_entry; - - /******************************* - * same RANDOM HAVOC for taint * - *******************************/ - -taint_havoc_stage: - - afl->stage_cur_byte = -1; - - /* The havoc stage mutation code is also invoked when splicing files; if the - splice_cycle variable is set, generate different descriptions and such. */ - - if (!splice_cycle) { - - afl->stage_name = "havoc"; - afl->stage_short = "havoc"; - afl->stage_max = (doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) * - perf_score / afl->havoc_div / 100; - - } else { - - perf_score = orig_perf; - - snprintf(afl->stage_name_buf, STAGE_BUF_SIZE, "splice %u", splice_cycle); - afl->stage_name = afl->stage_name_buf; - afl->stage_short = "splice"; - afl->stage_max = SPLICE_HAVOC * perf_score / afl->havoc_div / 100; - - } - - if (afl->stage_max < HAVOC_MIN) { afl->stage_max = HAVOC_MIN; } - - temp_len = len; - - orig_hit_cnt = afl->queued_paths + afl->unique_crashes; - - havoc_queued = afl->queued_paths; - - if (afl->custom_mutators_count) { - - LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { - - if (el->stacked_custom && el->afl_custom_havoc_mutation_probability) { - - el->stacked_custom_prob = - el->afl_custom_havoc_mutation_probability(el->data); - if (el->stacked_custom_prob > 100) { - - FATAL( - "The probability returned by " - "afl_custom_havoc_mutation_propability " - "has to be in the range 0-100."); - - } - - } - - }); - - } - - /* We essentially just do several thousand runs (depending on perf_score) - where we take the input file and make random stacked tweaks. */ - - if (unlikely(afl->expand_havoc)) { - - /* add expensive havoc cases here, they are activated after a full - cycle without finds happened */ - - r_max = 16 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0); - - } else { - - r_max = 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0); - - } - - for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { - - u32 use_stacking = 1 << (1 + rand_below(afl, HAVOC_STACK_POW2)); - - afl->stage_cur_val = use_stacking; - - for (i = 0; i < use_stacking; ++i) { - - if (afl->custom_mutators_count) { - - LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { - - if (el->stacked_custom && - rand_below(afl, 100) < el->stacked_custom_prob) { - - u8 * custom_havoc_buf = NULL; - size_t new_len = el->afl_custom_havoc_mutation( - el->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE); - if (unlikely(!custom_havoc_buf)) { - - FATAL("Error in custom_havoc (return %zd)", new_len); - - } - - if (likely(new_len > 0 && custom_havoc_buf)) { + clone_len = choose_block_len(afl, afl->queue_cur->len); + clone_from = + rand_below(afl, afl->queue_cur->len - clone_len + 1); - temp_len = new_len; - if (out_buf != custom_havoc_buf) { + } else { - ck_maybe_grow(BUF_PARAMS(out), temp_len); - memcpy(out_buf, custom_havoc_buf, temp_len); + clone_len = choose_block_len(afl, temp_len); + clone_from = rand_below(afl, temp_len - clone_len + 1); } - } - - } - - }); - - } - - switch ((r = rand_below(afl, r_max))) { - - case 0: - - /* Flip a single bit somewhere. Spooky! */ - - FLIP_BIT(out_buf, rand_below(afl, temp_len << 3)); - break; - - case 1: - - /* Set byte to interesting value. */ - - out_buf[rand_below(afl, temp_len)] = - interesting_8[rand_below(afl, sizeof(interesting_8))]; - break; - - case 2: - - /* Set word to interesting value, randomly choosing endian. */ - - if (temp_len < 2) { break; } - - if (rand_below(afl, 2)) { - - *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = - interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]; - - } else { - - *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = SWAP16( - interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]); - - } - - break; - - case 3: - - /* Set dword to interesting value, randomly choosing endian. */ - - if (temp_len < 4) { break; } - - if (rand_below(afl, 2)) { - - *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = - interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]; - - } else { - - *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = SWAP32( - interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]); - - } - - break; - - case 4: - - /* Randomly subtract from byte. */ - - out_buf[rand_below(afl, temp_len)] -= 1 + rand_below(afl, ARITH_MAX); - break; - - case 5: - - /* Randomly add to byte. */ - - out_buf[rand_below(afl, temp_len)] += 1 + rand_below(afl, ARITH_MAX); - break; - - case 6: - - /* Randomly subtract from word, random endian. */ - - if (temp_len < 2) { break; } - - if (rand_below(afl, 2)) { - - u32 pos = rand_below(afl, temp_len - 1); - - *(u16 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); - - } else { - - u32 pos = rand_below(afl, temp_len - 1); - u16 num = 1 + rand_below(afl, ARITH_MAX); - - *(u16 *)(out_buf + pos) = - SWAP16(SWAP16(*(u16 *)(out_buf + pos)) - num); - - } - - break; - - case 7: - - /* Randomly add to word, random endian. */ - - if (temp_len < 2) { break; } - - if (rand_below(afl, 2)) { - - u32 pos = rand_below(afl, temp_len - 1); - - *(u16 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); - - } else { - - u32 pos = rand_below(afl, temp_len - 1); - u16 num = 1 + rand_below(afl, ARITH_MAX); - - *(u16 *)(out_buf + pos) = - SWAP16(SWAP16(*(u16 *)(out_buf + pos)) + num); - - } - - break; - - case 8: - - /* Randomly subtract from dword, random endian. */ - - if (temp_len < 4) { break; } - - if (rand_below(afl, 2)) { - - u32 pos = rand_below(afl, temp_len - 3); - - *(u32 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); - - } else { - - u32 pos = rand_below(afl, temp_len - 3); - u32 num = 1 + rand_below(afl, ARITH_MAX); - - *(u32 *)(out_buf + pos) = - SWAP32(SWAP32(*(u32 *)(out_buf + pos)) - num); - - } - - break; - - case 9: - - /* Randomly add to dword, random endian. */ - - if (temp_len < 4) { break; } - - if (rand_below(afl, 2)) { - - u32 pos = rand_below(afl, temp_len - 3); - - *(u32 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); - - } else { - - u32 pos = rand_below(afl, temp_len - 3); - u32 num = 1 + rand_below(afl, ARITH_MAX); - - *(u32 *)(out_buf + pos) = - SWAP32(SWAP32(*(u32 *)(out_buf + pos)) + num); - - } - - break; - - case 10: - - /* Just set a random byte to a random value. Because, - why not. We use XOR with 1-255 to eliminate the - possibility of a no-op. */ - - out_buf[rand_below(afl, temp_len)] ^= 1 + rand_below(afl, 255); - break; - - case 11 ... 12: { - - /* Delete bytes. We're making this a bit more likely - than insertion (the next option) in hopes of keeping - files reasonably small. */ - - u32 del_from, del_len; - - if (temp_len < 2) { break; } - - /* Don't delete too much. */ - - del_len = choose_block_len(afl, temp_len - 1); - - del_from = rand_below(afl, temp_len - del_len + 1); - - memmove(out_buf + del_from, out_buf + del_from + del_len, - temp_len - del_from - del_len); - - temp_len -= del_len; - - break; - - } - - case 13: - - if (temp_len + HAVOC_BLK_XL < MAX_FILE) { - - /* Clone bytes (75%) or insert a block of constant bytes (25%). */ - - u8 actually_clone = rand_below(afl, 4); - u32 clone_from, clone_to, clone_len; - u8 *new_buf; - - if (actually_clone) { - - clone_len = choose_block_len(afl, temp_len); - clone_from = rand_below(afl, temp_len - clone_len + 1); - } else { clone_len = choose_block_len(afl, HAVOC_BLK_XL); @@ -2988,7 +2248,11 @@ taint_havoc_stage: if (actually_clone) { - memcpy(new_buf + clone_to, out_buf + clone_from, clone_len); + if (unlikely(afl->taint_needs_splode)) + memcpy(new_buf + clone_to, afl->taint_src + clone_from, + clone_len); + else + memcpy(new_buf + clone_to, out_buf + clone_from, clone_len); } else { @@ -3021,16 +2285,29 @@ taint_havoc_stage: if (temp_len < 2) { break; } - copy_len = choose_block_len(afl, temp_len - 1); + if (unlikely(afl->taint_needs_splode)) { + + copy_len = choose_block_len(afl, afl->queue_cur->len - 1); + copy_from = rand_below(afl, afl->queue_cur->len - copy_len + 1); + + } else { + + copy_len = choose_block_len(afl, temp_len - 1); + copy_from = rand_below(afl, temp_len - copy_len + 1); + + } - copy_from = rand_below(afl, temp_len - copy_len + 1); copy_to = rand_below(afl, temp_len - copy_len + 1); if (rand_below(afl, 4)) { if (copy_from != copy_to) { - memmove(out_buf + copy_to, out_buf + copy_from, copy_len); + if (unlikely(afl->taint_needs_splode)) + memmove(out_buf + copy_to, afl->taint_src + copy_from, + copy_len); + else + memmove(out_buf + copy_to, out_buf + copy_from, copy_len); } @@ -3296,10 +2573,17 @@ taint_havoc_stage: splices them together at some offset, then relies on the havoc code to mutate that blob. */ -taint_retry_splicing: + u32 saved_len; + + if (unlikely(afl->taint_needs_splode)) + saved_len = afl->taint_len; + else + saved_len = afl->queue_cur->len; + +retry_splicing: if (afl->use_splicing && splice_cycle++ < SPLICE_CYCLES && - afl->queued_paths > 1 && afl->queue_cur->len > 1) { + afl->queued_paths > 1 && saved_len > 1) { struct queue_entry *target; u32 tid, split_at; @@ -3312,7 +2596,7 @@ taint_retry_splicing: if (in_buf != orig_in) { in_buf = orig_in; - len = afl->queue_cur->len; + len = saved_len; } @@ -3336,7 +2620,7 @@ taint_retry_splicing: } - if (!target) { goto taint_retry_splicing; } + if (!target) { goto retry_splicing; } /* Read the testcase into a new buffer. */ @@ -3356,7 +2640,7 @@ taint_retry_splicing: locate_diffs(in_buf, new_buf, MIN(len, (s64)target->len), &f_diff, &l_diff); - if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { goto taint_retry_splicing; } + if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { goto retry_splicing; } /* Split somewhere between the first and last differing byte. */ @@ -3381,13 +2665,10 @@ taint_retry_splicing: #endif /* !IGNORE_FINDS */ - - ret_val = 0; goto abandon_entry; - /* we are through with this queue entry - for this iteration */ abandon_entry: -- cgit v1.2.3 From 9ec223c844a9fd9d8b66e309517fd7c64e5d4c5e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 9 Aug 2020 23:47:51 +0200 Subject: final touches for first testing --- src/afl-fuzz-one.c | 58 ++++++++++++++++++++++++++++++------------------------ src/afl-fuzz-run.c | 4 +++- 2 files changed, 35 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 75381db8..beb73246 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -458,16 +458,17 @@ u8 fuzz_one_original(afl_state_t *afl) { } - u32 tmp_val; + u32 tmp_val = 0; - if (unlikely(afl->fsrv.taint_mode && - (tmp_val = (afl->queue_cycle % 3)) != 1)) { + if (unlikely(afl->fsrv.taint_mode)) { + tmp_val = afl->queue_cycle % 2; ret_val = 0; if (unlikely(afl->queue_cur->cal_failed)) goto abandon_entry; + if (unlikely(!afl->queue_cur->passed_det) && !tmp_val) goto abandon_entry; if (tmp_val == 1 && !afl->queue_cur->taint_bytes_all) goto abandon_entry; - if (tmp_val == 2 && !afl->queue_cur->taint_bytes_new) goto abandon_entry; + if (tmp_val == 0 && !afl->queue_cur->taint_bytes_new) goto abandon_entry; ret_val = 1; @@ -483,10 +484,7 @@ u8 fuzz_one_original(afl_state_t *afl) { switch (tmp_val) { - case 1: // do nothing, but cannot happen -> else - break; - - case 2: // fuzz only tainted bytes + case 1: // fuzz only tainted bytes fd = open(afl->taint_input_file, O_RDONLY); temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_all; @@ -536,9 +534,10 @@ u8 fuzz_one_original(afl_state_t *afl) { } else { - /* Map the test case into memory. */ afl->taint_needs_splode = 0; + /* Map the test case into memory. */ + fd = open(afl->queue_cur->fname, O_RDONLY); if (unlikely(fd < 0)) { @@ -565,7 +564,7 @@ u8 fuzz_one_original(afl_state_t *afl) { single byte anyway, so it wouldn't give us any performance or memory usage benefits. */ - out_buf = ck_maybe_grow(BUF_PARAMS(out), len); + out_buf = ck_maybe_grow(BUF_PARAMS(out), len + 4096); afl->subseq_tmouts = 0; @@ -575,7 +574,8 @@ u8 fuzz_one_original(afl_state_t *afl) { * CALIBRATION (only if failed earlier on) * *******************************************/ - if (unlikely(afl->queue_cur->cal_failed)) { + if (unlikely(afl->queue_cur->cal_failed && + (!afl->taint_needs_splode || tmp_val == 1))) { u8 res = FSRV_RUN_TMOUT; @@ -659,9 +659,6 @@ u8 fuzz_one_original(afl_state_t *afl) { if it has gone through deterministic testing in earlier, resumed runs (passed_det). */ - // custom mutators would not work, deterministic is done -> so havoc! - if (afl->taint_needs_splode) goto havoc_stage; - if (likely(afl->queue_cur->passed_det) || likely(afl->skip_deterministic) || likely(perf_score < (afl->queue_cur->depth * 30 <= afl->havoc_max_mult * 100 @@ -1640,7 +1637,7 @@ skip_interest: orig_hit_cnt = new_hit_cnt; - ex_tmp = ck_maybe_grow(BUF_PARAMS(ex), len + MAX_DICT_FILE); + ex_tmp = ck_maybe_grow(BUF_PARAMS(ex), len + MAX_DICT_FILE + 4096); for (i = 0; i <= (u32)len; ++i) { @@ -1814,7 +1811,7 @@ custom_mutator_stage: fd = open(target->fname, O_RDONLY); if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); } - new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), target->len); + new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), target->len + 4096); ck_read(fd, new_buf, target->len, target->fname); close(fd); @@ -1989,7 +1986,7 @@ havoc_stage: temp_len = new_len; if (out_buf != custom_havoc_buf) { - ck_maybe_grow(BUF_PARAMS(out), temp_len); + ck_maybe_grow(BUF_PARAMS(out), temp_len + 4096); memcpy(out_buf, custom_havoc_buf, temp_len); } @@ -2237,8 +2234,8 @@ havoc_stage: clone_to = rand_below(afl, temp_len); - new_buf = - ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); + new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), + temp_len + clone_len + 4096); /* Head */ @@ -2303,10 +2300,18 @@ havoc_stage: if (copy_from != copy_to) { - if (unlikely(afl->taint_needs_splode)) + if (unlikely(afl->taint_needs_splode)) { + + if (copy_to > temp_len) copy_to = rand_below(afl, temp_len); + + // fprintf(stderr, "\nout_buf %p + copy_to %u, src %p + %u, + // copy_len %u -- len %u\n", out_buf , copy_to, afl->taint_src , + // copy_from, copy_len, afl->taint_len, afl->queue_cur->len); memmove(out_buf + copy_to, afl->taint_src + copy_from, copy_len); - else + + } else + memmove(out_buf + copy_to, out_buf + copy_from, copy_len); } @@ -2395,7 +2400,8 @@ havoc_stage: if (temp_len + extra_len >= MAX_FILE) { break; } - out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len); + out_buf = + ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len + 4096); /* Tail */ memmove(out_buf + insert_at + extra_len, out_buf + insert_at, @@ -2490,8 +2496,8 @@ havoc_stage: clone_to = rand_below(afl, temp_len); - u8 *temp_buf = - ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); + u8 *temp_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), + temp_len + clone_len + 4096); /* Head */ @@ -2526,7 +2532,7 @@ havoc_stage: /* out_buf might have been mangled a bit, so let's restore it to its original size and shape. */ - out_buf = ck_maybe_grow(BUF_PARAMS(out), len); + out_buf = ck_maybe_grow(BUF_PARAMS(out), len + 4096); temp_len = len; memcpy(out_buf, in_buf, len); @@ -2653,7 +2659,7 @@ retry_splicing: swap_bufs(BUF_PARAMS(in), BUF_PARAMS(in_scratch)); in_buf = new_buf; - out_buf = ck_maybe_grow(BUF_PARAMS(out), len); + out_buf = ck_maybe_grow(BUF_PARAMS(out), len + 4096); memcpy(out_buf, in_buf, len); goto custom_mutator_stage; diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 31db4d7c..41de143c 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -349,7 +349,9 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, } - if (q->exec_cksum) { + if (unlikely(afl->fsrv.taint_mode)) + q->exec_cksum = 0; + else if (q->exec_cksum) { memcpy(afl->first_trace, afl->fsrv.trace_bits, afl->fsrv.map_size); hnb = has_new_bits(afl, afl->virgin_bits); -- cgit v1.2.3 From 8f8555dfdfeee643795ba04cd4240db40a88711e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 10 Aug 2020 12:05:30 +0200 Subject: fix segfault --- src/afl-fuzz-one.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index beb73246..c664f281 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2295,6 +2295,7 @@ havoc_stage: } copy_to = rand_below(afl, temp_len - copy_len + 1); + if (unlikely(copy_to > temp_len)) copy_to = rand_below(afl, temp_len); if (rand_below(afl, 4)) { -- cgit v1.2.3 From 84b9d551fd288a836941975adc7ec0984ef54b0a Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 10 Aug 2020 12:11:49 +0200 Subject: disable expand havoc mopt for taint --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 70a99dec..2b9af94c 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1381,7 +1381,7 @@ int main(int argc, char **argv_orig, char **envp) { break; case 1: if (afl->limit_time_sig == 0 && !afl->custom_only && - !afl->python_only) { + !afl->python_only && !afl->fsrv.taint_mode) { afl->limit_time_sig = -1; afl->limit_time_puppet = 0; -- cgit v1.2.3 From f181a8307b9544a24e2c737e748e9ff34e8620e1 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 10 Aug 2020 12:48:15 +0200 Subject: put ! in .new map --- src/afl-fuzz-queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 3ada9d98..28af17f0 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -178,7 +178,7 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname, for (i = 0; i < len; i++) if (afl->taint_fsrv.trace_bits[i] && (i >= prev->len || !bufr[i])) - tmp[i] = 1; + tmp[i] = '!'; q->taint_bytes_new = count_bytes_len(afl, tmp, plen); -- cgit v1.2.3 From 9c953ab51ff22b2fc3e1b73e6563211e7676b62e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 10 Aug 2020 13:03:59 +0200 Subject: memory grab at startup to prevent crashes --- src/afl-fuzz-one.c | 18 +++++++++--------- src/afl-fuzz.c | 11 +++++++++++ 2 files changed, 20 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index c664f281..75687703 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -564,7 +564,7 @@ u8 fuzz_one_original(afl_state_t *afl) { single byte anyway, so it wouldn't give us any performance or memory usage benefits. */ - out_buf = ck_maybe_grow(BUF_PARAMS(out), len + 4096); + out_buf = ck_maybe_grow(BUF_PARAMS(out), len); afl->subseq_tmouts = 0; @@ -1637,7 +1637,7 @@ skip_interest: orig_hit_cnt = new_hit_cnt; - ex_tmp = ck_maybe_grow(BUF_PARAMS(ex), len + MAX_DICT_FILE + 4096); + ex_tmp = ck_maybe_grow(BUF_PARAMS(ex), len + MAX_DICT_FILE); for (i = 0; i <= (u32)len; ++i) { @@ -1811,7 +1811,7 @@ custom_mutator_stage: fd = open(target->fname, O_RDONLY); if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); } - new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), target->len + 4096); + new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), target->len); ck_read(fd, new_buf, target->len, target->fname); close(fd); @@ -1986,7 +1986,7 @@ havoc_stage: temp_len = new_len; if (out_buf != custom_havoc_buf) { - ck_maybe_grow(BUF_PARAMS(out), temp_len + 4096); + ck_maybe_grow(BUF_PARAMS(out), temp_len); memcpy(out_buf, custom_havoc_buf, temp_len); } @@ -2235,7 +2235,7 @@ havoc_stage: clone_to = rand_below(afl, temp_len); new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), - temp_len + clone_len + 4096); + temp_len + clone_len); /* Head */ @@ -2402,7 +2402,7 @@ havoc_stage: if (temp_len + extra_len >= MAX_FILE) { break; } out_buf = - ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len + 4096); + ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len); /* Tail */ memmove(out_buf + insert_at + extra_len, out_buf + insert_at, @@ -2498,7 +2498,7 @@ havoc_stage: clone_to = rand_below(afl, temp_len); u8 *temp_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), - temp_len + clone_len + 4096); + temp_len + clone_len); /* Head */ @@ -2533,7 +2533,7 @@ havoc_stage: /* out_buf might have been mangled a bit, so let's restore it to its original size and shape. */ - out_buf = ck_maybe_grow(BUF_PARAMS(out), len + 4096); + out_buf = ck_maybe_grow(BUF_PARAMS(out), len); temp_len = len; memcpy(out_buf, in_buf, len); @@ -2660,7 +2660,7 @@ retry_splicing: swap_bufs(BUF_PARAMS(in), BUF_PARAMS(in_scratch)); in_buf = new_buf; - out_buf = ck_maybe_grow(BUF_PARAMS(out), len + 4096); + out_buf = ck_maybe_grow(BUF_PARAMS(out), len); memcpy(out_buf, in_buf, len); goto custom_mutator_stage; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 2b9af94c..5cdd0292 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1305,6 +1305,17 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Taint forkserver successfully started"); +#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size + u8 *tmp1 = ck_maybe_grow(BUF_PARAMS(eff), MAX_FILE + 4096); + u8 *tmp2 = ck_maybe_grow(BUF_PARAMS(ex), MAX_FILE + 4096); + u8 *tmp3 = ck_maybe_grow(BUF_PARAMS(in_scratch), MAX_FILE + 4096); + u8 *tmp4 = ck_maybe_grow(BUF_PARAMS(out), MAX_FILE + 4096); + u8 *tmp5 = ck_maybe_grow(BUF_PARAMS(out_scratch), MAX_FILE + 4096); +#undef BUF_PARAMS + + if (!tmp1 || !tmp2 || !tmp3 || !tmp4 || !tmp5) + FATAL("memory issues. me hungry, feed me!"); + } perform_dry_run(afl); -- cgit v1.2.3 From 8428b18d2a48cf7e995797a8b2183920aaa14f7e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 10 Aug 2020 13:30:25 +0200 Subject: fix another segfault --- src/afl-fuzz-run.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 41de143c..7180d255 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -879,12 +879,13 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { s32 new_len = afl->queue_cur->len + len - afl->taint_len; if (new_len < 4) new_len = 4; + if (new_len > MAX_FILE) new_len = MAX_FILE; u8 *new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), new_len); u32 i, taint = 0; for (i = 0; i < new_len; i++) { - if (afl->taint_map[i] || i > afl->queue_cur->len) + if (i > afl->taint_len || afl->taint_map[i] || i > afl->queue_cur->len) new_buf[i] = out_buf[taint++]; else new_buf[i] = afl->taint_src[i]; -- cgit v1.2.3 From 3ecafde29deac10bb41c6c9b7370f7cef951ef11 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 10 Aug 2020 13:59:30 +0200 Subject: increase stack size --- src/afl-common.c | 4 ++-- src/afl-fuzz-run.c | 2 +- src/afl-fuzz.c | 7 ++++++- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index e01bde3c..dabeeedd 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -467,8 +467,8 @@ void read_bitmap(u8 *fname, u8 *map, size_t len) { u64 get_cur_time(void) { - struct timeval tv; - struct timezone tz; + static struct timeval tv; + static struct timezone tz; gettimeofday(&tv, &tz); diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 7180d255..0aef1c9e 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -885,7 +885,7 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { u32 i, taint = 0; for (i = 0; i < new_len; i++) { - if (i > afl->taint_len || afl->taint_map[i] || i > afl->queue_cur->len) + if (i >= afl->taint_len || i >= afl->queue_cur->len || afl->taint_map[i]) new_buf[i] = out_buf[taint++]; else new_buf[i] = afl->taint_src[i]; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 5cdd0292..783da6e0 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1305,6 +1305,12 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Taint forkserver successfully started"); + const rlim_t kStackSize = 64L * 1024L * 1024L; // min stack size = 64 Mb + struct rlimit rl; + rl.rlim_cur = kStackSize; + if (getrlimit(RLIMIT_STACK, &rl) != 0) + WARNF("Setting a higher stack size failed!"); + #define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size u8 *tmp1 = ck_maybe_grow(BUF_PARAMS(eff), MAX_FILE + 4096); u8 *tmp2 = ck_maybe_grow(BUF_PARAMS(ex), MAX_FILE + 4096); @@ -1312,7 +1318,6 @@ int main(int argc, char **argv_orig, char **envp) { u8 *tmp4 = ck_maybe_grow(BUF_PARAMS(out), MAX_FILE + 4096); u8 *tmp5 = ck_maybe_grow(BUF_PARAMS(out_scratch), MAX_FILE + 4096); #undef BUF_PARAMS - if (!tmp1 || !tmp2 || !tmp3 || !tmp4 || !tmp5) FATAL("memory issues. me hungry, feed me!"); -- cgit v1.2.3 From a422fcaa40a3c7cd577b693060d9bc2e6c36cf73 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 10 Aug 2020 19:04:51 +0200 Subject: fixed minor inconsistencies, reenabled warnings --- src/afl-fuzz-cmplog.c | 4 ---- src/afl-fuzz-run.c | 2 +- src/afl-fuzz.c | 3 ++- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c index faf4dcb7..8ffc6e1b 100644 --- a/src/afl-fuzz-cmplog.c +++ b/src/afl-fuzz-cmplog.c @@ -29,10 +29,6 @@ #include "afl-fuzz.h" #include "cmplog.h" -typedef struct cmplog_data { - -} cmplog_data_t; - void cmplog_exec_child(afl_forkserver_t *fsrv, char **argv) { setenv("___AFL_EINS_ZWEI_POLIZEI___", "1", 1); diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 8d652155..e69e9791 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -138,7 +138,7 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { /* The same, but with an adjustable gap. Used for trimming. */ -static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at, +static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at, u32 skip_len) { s32 fd = afl->fsrv.out_fd; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 031c4049..009eaa12 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -289,8 +289,9 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->cpu_to_bind != -1) FATAL("Multiple -b options not supported"); - if (sscanf(optarg, "%u", &afl->cpu_to_bind) < 0 || optarg[0] == '-') + if (sscanf(optarg, "%d", &afl->cpu_to_bind) < 0) { FATAL("Bad syntax used for -b"); + } break; -- cgit v1.2.3 From 7d7a8c7c39173c340a53868891d65b4477c296c0 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 10 Aug 2020 19:05:22 +0200 Subject: code-format --- src/afl-fuzz.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 009eaa12..5dd092f2 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -290,7 +290,9 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->cpu_to_bind != -1) FATAL("Multiple -b options not supported"); if (sscanf(optarg, "%d", &afl->cpu_to_bind) < 0) { + FATAL("Bad syntax used for -b"); + } break; -- cgit v1.2.3 From 701fb95d24cd754e9c116d81502b6057a29eb2bd Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 10 Aug 2020 23:42:33 +0200 Subject: LTO: make dynamic map the default --- src/afl-forkserver.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 752641d7..1ececf27 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -293,8 +293,8 @@ static void report_error_and_exit(int error) { FATAL( "the fuzzing target reports that hardcoded map address might be the " "reason the mmap of the shared memory failed. Solution: recompile " - "the target with either afl-clang-lto and the environment variable " - "AFL_LLVM_MAP_DYNAMIC set or recompile with afl-clang-fast."); + "the target with either afl-clang-lto and do not set " + "AFL_LLVM_MAP_ADDR or recompile with afl-clang-fast."); break; case FS_ERROR_SHM_OPEN: FATAL("the fuzzing target reports that the shm_open() call failed."); @@ -828,8 +828,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, SAYF("\n" cLRD "[-] " cRST "Hmm, looks like the target binary terminated before we could" " complete a handshake with the injected code.\n" - "If the target was compiled with afl-clang-lto then recompiling with" - " AFL_LLVM_MAP_DYNAMIC might solve your problem.\n" + "If the target was compiled with afl-clang-lto and AFL_LLVM_MAP_ADDR" + " then recompiling without this parameter.\n" "Otherwise there is a horrible bug in the fuzzer.\n" "Poke for troubleshooting tips.\n"); @@ -860,9 +860,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, " - the target was compiled with afl-clang-lto and a constructor " "was\n" - " instrumented, recompiling with AFL_LLVM_MAP_DYNAMIC might solve " - "your\n" - " problem\n\n" + " instrumented, recompiling without AFL_LLVM_MAP_ADDR might solve " + "your problem\n\n" " - Less likely, there is a horrible bug in the fuzzer. If other " "options\n" -- cgit v1.2.3 From 9cf8637fab8cf3fe8aba5660015bbe7177805807 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 11 Aug 2020 03:37:02 +0200 Subject: break up llvm rt afl init --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 783da6e0..fc9cbb6c 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1305,7 +1305,7 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Taint forkserver successfully started"); - const rlim_t kStackSize = 64L * 1024L * 1024L; // min stack size = 64 Mb + const rlim_t kStackSize = 256L * 1024L * 1024L; // min stack size = 256 Mb struct rlimit rl; rl.rlim_cur = kStackSize; if (getrlimit(RLIMIT_STACK, &rl) != 0) -- cgit v1.2.3 From 0ba09ee85a65878e70d1a224f9d41fcbac3ff1e5 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 11 Aug 2020 10:24:45 +0200 Subject: enhancements --- src/afl-common.c | 30 +++++++++++++++++------------- src/afl-fuzz-one.c | 11 +++++------ src/afl-fuzz.c | 11 +++++------ 3 files changed, 27 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index dabeeedd..c1302080 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -138,7 +138,7 @@ void argv_cpy_free(char **argv) { } -u8 *find_binary_own_loc(u8 *fname, u8 *own_loc) { +u8 *find_afl_binary(u8 *fname, u8 *own_loc) { u8 *tmp, *rsl, *own_copy, *cp; @@ -154,21 +154,25 @@ u8 *find_binary_own_loc(u8 *fname, u8 *own_loc) { } - own_copy = ck_strdup(own_loc); - rsl = strrchr(own_copy, '/'); + if (own_loc) { - if (rsl) { + own_copy = ck_strdup(own_loc); + rsl = strrchr(own_copy, '/'); - *rsl = 0; + if (rsl) { - cp = alloc_printf("%s/%s", own_copy, fname); - ck_free(own_copy); + *rsl = 0; - if (!access(cp, X_OK)) { return cp; } + cp = alloc_printf("%s/%s", own_copy, fname); + ck_free(own_copy); - } else { + if (!access(cp, X_OK)) { return cp; } + + } else { - ck_free(own_copy); + ck_free(own_copy); + + } } @@ -196,7 +200,7 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { /* Now we need to actually find the QEMU binary to put in argv[0]. */ - cp = find_binary_own_loc("afl-qemu-trace", own_loc); + cp = find_afl_binary("afl-qemu-trace", own_loc); if (cp) { @@ -241,12 +245,12 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { /* Now we need to actually find the QEMU binary to put in argv[0]. */ - cp = find_binary_own_loc("afl-qemu-trace", own_loc); + cp = find_afl_binary("afl-qemu-trace", own_loc); if (cp) { ck_free(cp); - cp = find_binary_own_loc("afl-wine-trace", own_loc); + cp = find_afl_binary("afl-wine-trace", own_loc); if (cp) { diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 9f38b8f8..2f724569 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2236,8 +2236,8 @@ havoc_stage: clone_to = rand_below(afl, temp_len); - new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), - temp_len + clone_len); + new_buf = + ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); /* Head */ @@ -2403,8 +2403,7 @@ havoc_stage: if (temp_len + extra_len >= MAX_FILE) { break; } - out_buf = - ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len); + out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len); /* Tail */ memmove(out_buf + insert_at + extra_len, out_buf + insert_at, @@ -2499,8 +2498,8 @@ havoc_stage: clone_to = rand_below(afl, temp_len); - u8 *temp_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), - temp_len + clone_len); + u8 *temp_buf = + ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); /* Head */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 11db004d..d2b2c2d9 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1274,9 +1274,8 @@ int main(int argc, char **argv_orig, char **envp) { ck_free(afl->taint_fsrv.target_path); afl->argv_taint = ck_alloc(sizeof(char *) * (argc + 4 - optind)); - afl->taint_fsrv.target_path = - find_binary_own_loc("afl-qemu-taint", argv[0]); - afl->argv_taint[0] = find_binary_own_loc("afl-qemu-taint", argv[0]); + afl->taint_fsrv.target_path = find_afl_binary("afl-qemu-taint", argv[0]); + afl->argv_taint[0] = find_afl_binary("afl-qemu-taint", argv[0]); if (!afl->argv_taint[0]) FATAL( "Cannot find 'afl-qemu-taint', read qemu_taint/README.md on how to " @@ -1308,19 +1307,19 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Taint forkserver successfully started"); - const rlim_t kStackSize = 256L * 1024L * 1024L; // min stack size = 256 Mb + const rlim_t kStackSize = 256L * 1024L * 1024L; // min stack size = 256 Mb struct rlimit rl; rl.rlim_cur = kStackSize; if (getrlimit(RLIMIT_STACK, &rl) != 0) WARNF("Setting a higher stack size failed!"); -#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size + #define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size u8 *tmp1 = ck_maybe_grow(BUF_PARAMS(eff), MAX_FILE + 4096); u8 *tmp2 = ck_maybe_grow(BUF_PARAMS(ex), MAX_FILE + 4096); u8 *tmp3 = ck_maybe_grow(BUF_PARAMS(in_scratch), MAX_FILE + 4096); u8 *tmp4 = ck_maybe_grow(BUF_PARAMS(out), MAX_FILE + 4096); u8 *tmp5 = ck_maybe_grow(BUF_PARAMS(out_scratch), MAX_FILE + 4096); -#undef BUF_PARAMS + #undef BUF_PARAMS if (!tmp1 || !tmp2 || !tmp3 || !tmp4 || !tmp5) FATAL("memory issues. me hungry, feed me!"); -- cgit v1.2.3 From 3ec1b2374336d0b98aa4fc586cd5bc601b711821 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 11 Aug 2020 10:36:34 +0200 Subject: cleanup minor issues --- src/afl-fuzz-bitmap.c | 4 ++++ src/afl-fuzz-one.c | 22 ++++++++++++---------- src/afl-fuzz-queue.c | 3 +-- src/afl-fuzz-run.c | 2 +- src/afl-fuzz.c | 2 +- 5 files changed, 19 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index d4ee36e1..9f58d604 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -183,6 +183,8 @@ u32 count_bits_len(afl_state_t *afl, u8 *mem, u32 len) { u32 i = (len >> 2); u32 ret = 0; + (void)(afl); + if (len % 4) i++; while (i--) { @@ -241,6 +243,8 @@ u32 count_bytes_len(afl_state_t *afl, u8 *mem, u32 len) { u32 i = (len >> 2); u32 ret = 0; + (void)(afl); + while (i--) { u32 v = *(ptr++); diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 2f724569..4b2fd90a 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -472,12 +472,12 @@ u8 fuzz_one_original(afl_state_t *afl) { ret_val = 1; - u32 dst = 0, i; + s32 dst = 0, i; temp_len = len = afl->queue_cur->len; fd = open(afl->queue_cur->fname, O_RDONLY); afl->taint_src = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (fd < 0 || (size_t)afl->taint_src == -1) + if (fd < 0 || (ssize_t)afl->taint_src == -1) FATAL("unable to open '%s'", afl->queue_cur->fname); close(fd); afl->taint_needs_splode = 1; @@ -490,18 +490,18 @@ u8 fuzz_one_original(afl_state_t *afl) { temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_all; orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (fd < 0 || (size_t)in_buf == -1) + if (fd < 0 || (ssize_t)in_buf == -1) FATAL("unable to open '%s'", afl->taint_input_file); close(fd); fd = open(afl->queue_cur->fname_taint, O_RDWR); afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (fd < 0 || (size_t)in_buf == -1) + if (fd < 0 || (ssize_t)in_buf == -1) FATAL("unable to open '%s'", afl->queue_cur->fname_taint); close(fd); - for (i = 0; i < afl->queue_cur->len && dst < len; i++) + for (i = 0; i < (s32)afl->queue_cur->len && dst < len; i++) if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i]; break; @@ -512,7 +512,7 @@ u8 fuzz_one_original(afl_state_t *afl) { temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_new; orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (fd < 0 || (size_t)in_buf == -1) + if (fd < 0 || (ssize_t)in_buf == -1) FATAL("unable to open '%s'", afl->taint_input_file); close(fd); @@ -520,12 +520,12 @@ u8 fuzz_one_original(afl_state_t *afl) { fd = open(fn, O_RDWR); afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (fd < 0 || (size_t)in_buf == -1) + if (fd < 0 || (ssize_t)in_buf == -1) FATAL("unable to open '%s' for %u bytes", fn, len); close(fd); ck_free(fn); - for (i = 0; i < afl->queue_cur->len && dst < len; i++) + for (i = 0; i < (s32)afl->queue_cur->len && dst < len; i++) if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i]; break; @@ -2297,7 +2297,8 @@ havoc_stage: } copy_to = rand_below(afl, temp_len - copy_len + 1); - if (unlikely(copy_to > temp_len)) copy_to = rand_below(afl, temp_len); + if (unlikely(copy_to > (u32)temp_len)) + copy_to = rand_below(afl, temp_len); if (rand_below(afl, 4)) { @@ -2305,7 +2306,8 @@ havoc_stage: if (unlikely(afl->taint_needs_splode)) { - if (copy_to > temp_len) copy_to = rand_below(afl, temp_len); + if (copy_to > (u32)temp_len) + copy_to = rand_below(afl, temp_len); // fprintf(stderr, "\nout_buf %p + copy_to %u, src %p + %u, // copy_len %u -- len %u\n", out_buf , copy_to, afl->taint_src , diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 28af17f0..f4b58a9d 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -108,7 +108,6 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname, u8 * ptr, *fn = fname; u32 bytes = 0, plen = len; - s32 fd = -1; struct queue_entry *prev = q->prev; if (plen % 4) plen = plen + 4 - (len % 4); @@ -170,7 +169,7 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname, u8 *bufr = mmap(0, prev->len, PROT_READ, MAP_PRIVATE, r, 0); - if ((size_t)bufr != -1) { + if ((ssize_t)bufr != -1) { u32 i; u8 *tmp = ck_maybe_grow(BUF_PARAMS(in_scratch), plen); diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 9db23134..058f8c2d 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -883,7 +883,7 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { u8 *new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), new_len); u32 i, taint = 0; - for (i = 0; i < new_len; i++) { + for (i = 0; i < (u32)new_len; i++) { if (i >= afl->taint_len || i >= afl->queue_cur->len || afl->taint_map[i]) new_buf[i] = out_buf[taint++]; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index d2b2c2d9..e6238366 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1095,7 +1095,7 @@ int main(int argc, char **argv_orig, char **envp) { if (map_size != real_map_size) { afl->fsrv.map_size = real_map_size; - if (afl->cmplog_binary) afl->cmplog_fsrv.map_size; + if (afl->cmplog_binary) afl->cmplog_fsrv.map_size = real_map_size; } -- cgit v1.2.3 From 4f695b6f4c3ced165703363904e42492fca82112 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 11 Aug 2020 11:16:48 +0200 Subject: fixes --- src/afl-common.c | 4 +-- src/afl-fuzz-bitmap.c | 2 ++ src/afl-fuzz-queue.c | 78 +++++++++++++++++++++++++++++++++++---------------- src/afl-fuzz-stats.c | 5 ++-- 4 files changed, 61 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index c1302080..cefed8dc 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -471,8 +471,8 @@ void read_bitmap(u8 *fname, u8 *map, size_t len) { u64 get_cur_time(void) { - static struct timeval tv; - static struct timezone tz; + struct timeval tv; + struct timezone tz; gettimeofday(&tv, &tz); diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 9f58d604..d273818d 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -245,6 +245,8 @@ u32 count_bytes_len(afl_state_t *afl, u8 *mem, u32 len) { (void)(afl); + if (len % 4) i++; + while (i--) { u32 v = *(ptr++); diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index f4b58a9d..b56e10f8 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -125,42 +125,64 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname, if (afl_fsrv_run_target(&afl->taint_fsrv, afl->fsrv.exec_tmout, &afl->stop_soon) == 0) { - bytes = count_bytes_len(afl, afl->taint_fsrv.trace_bits, plen); + bytes = q->taint_bytes_all = + count_bytes_len(afl, afl->taint_fsrv.trace_bits, plen); if (afl->debug) fprintf(stderr, "Debug: tainted %u out of %u bytes\n", bytes, len); - if (bytes) { + /* DEBUG FIXME TODO XXX */ + u32 i; + for (i = 0; i < len; i++) { - s32 i = len; - while (i > 0 && !afl->taint_fsrv.trace_bits[i - 1]) - i--; - q->taint_bytes_highest = i; + if (afl->taint_fsrv.trace_bits[i] && + afl->taint_fsrv.trace_bits[i] != '!') + FATAL("invalid taint map value %02x at pos %d", + afl->taint_fsrv.trace_bits[i], i); } - } + if (len < plen) + for (i = len; i < plen; i++) { - if (((bytes * 100) / len) < 90) { + if (afl->taint_fsrv.trace_bits[i]) + FATAL("invalid taint map value %02x in padding at pos %d", + afl->taint_fsrv.trace_bits[i], i); - // we only use the taint havoc mode if the entry has less than 90% of - // overall tainted bytes - q->taint_bytes_all = bytes; + } + + } + + // if all is tainted we do not need to write taint data away + if (bytes && bytes < len) { // save the bytes away int w = open(q->fname_taint, O_CREAT | O_WRONLY, 0644); if (w >= 0) { - ck_write(w, afl->taint_fsrv.trace_bits, plen, q->fname_taint); + ck_write(w, afl->taint_fsrv.trace_bits, len, q->fname_taint); close(w); + // find the highest tainted offset in the input (for trim opt) + s32 i = len; + while (i > 0 && !afl->taint_fsrv.trace_bits[i - 1]) + i--; + q->taint_bytes_highest = i; + + afl->taint_count++; + } else { FATAL("could not create %s", q->fname_taint); - bytes = 0; + q->taint_bytes_all = bytes = 0; } - if (bytes && prev && prev->taint_bytes_all) { + // it is possible that there is no main taint file - if the whole file + // is tainted - but a .new taint file if it had new tainted bytes + + // check if there is a previous queue entry and if it had taint + if (bytes && prev && prev->taint_bytes_all && + prev->taint_bytes_all < prev->len) { // check if there are new bytes in the taint vs the previous int r = open(prev->fname_taint, O_RDONLY); @@ -181,14 +203,28 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname, q->taint_bytes_new = count_bytes_len(afl, tmp, plen); + if (afl->debug) + fprintf(stderr, "Debug: %u new taint out of %u bytes\n", bytes, + len); + if (q->taint_bytes_new) { u8 *fnw = alloc_printf("%s.new", q->fname_taint); - int w = open(fnw, O_CREAT | O_WRONLY, 0644); - if (w >= 0) { + if (fnw) { + + int w = open(fnw, O_CREAT | O_WRONLY, 0644); + if (w >= 0) { + + ck_write(w, tmp, plen, fnw); + close(w); - ck_write(w, tmp, plen, fnw); - close(w); + } else { + + q->taint_bytes_new = 0; + + } + + ck_free(fnw); } else { @@ -196,8 +232,6 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname, } - ck_free(fnw); - } munmap(bufr, prev->len); @@ -210,10 +244,6 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname, } - } else { - - bytes = 0; - } memcpy(afl->taint_fsrv.trace_bits, save, afl->fsrv.map_size); diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index aeb290bd..0cc06e12 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -116,6 +116,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, "edges_found : %u\n" "var_byte_count : %u\n" "havoc_expansion : %u\n" + "tainted_inputs : %u\n" "afl_banner : %s\n" "afl_version : " VERSION "\n" @@ -149,8 +150,8 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, #else -1, #endif - t_bytes, afl->var_byte_count, afl->expand_havoc, afl->use_banner, - afl->unicorn_mode ? "unicorn" : "", + t_bytes, afl->var_byte_count, afl->expand_havoc, afl->taint_count, + afl->use_banner, afl->unicorn_mode ? "unicorn" : "", afl->fsrv.qemu_mode ? "qemu " : "", afl->non_instrumented_mode ? " non_instrumented " : "", afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "", -- cgit v1.2.3 From 457f627101c08b885e9edfd8b491b5be198b6f14 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 11 Aug 2020 15:10:18 +0200 Subject: move taint_mode var --- src/afl-forkserver.c | 2 +- src/afl-fuzz-init.c | 6 +++--- src/afl-fuzz-one.c | 2 +- src/afl-fuzz-queue.c | 3 ++- src/afl-fuzz-run.c | 2 +- src/afl-fuzz.c | 30 ++++++++++++++++-------------- 6 files changed, 24 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index adb75a2d..56475320 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -497,7 +497,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, char pid_buf[16]; sprintf(pid_buf, "%d", fsrv->fsrv_pid); - if (fsrv->qemu_mode == 2) { + if (fsrv->taint_mode) { setenv("__AFL_TARGET_PID3", pid_buf, 1); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 432e0649..669bd65a 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -961,7 +961,7 @@ void perform_dry_run(afl_state_t *afl) { } /* perform taint gathering on the input seed */ - if (afl->fsrv.taint_mode) + if (afl->taint_mode) perform_taint_run(afl, q, q->fname, use_mem, q->len); q = q->next; @@ -1502,7 +1502,7 @@ static void handle_existing_out_dir(afl_state_t *afl) { if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); - if (afl->fsrv.taint_mode) { + if (afl->taint_mode) { fn = alloc_printf("%s/taint", afl->out_dir); mkdir(fn, 0755); // ignore errors @@ -1745,7 +1745,7 @@ void setup_dirs_fds(afl_state_t *afl) { /* Taint directory if taint_mode. */ - if (afl->fsrv.taint_mode) { + if (afl->taint_mode) { tmp = alloc_printf("%s/taint", afl->out_dir); if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 4b2fd90a..69f885ca 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -460,7 +460,7 @@ u8 fuzz_one_original(afl_state_t *afl) { u32 tmp_val = 0; - if (unlikely(afl->fsrv.taint_mode)) { + if (unlikely(afl->taint_mode)) { tmp_val = afl->queue_cycle % 2; ret_val = 0; diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index b56e10f8..bb44e465 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -220,6 +220,7 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname, } else { + FATAL("count not create '%s'", fnw); q->taint_bytes_new = 0; } @@ -419,7 +420,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u8 *mem, u32 len, afl->last_path_time = get_cur_time(); /* trigger the tain gathering if this is not a dry run */ - if (afl->fsrv.taint_mode && mem) { + if (afl->taint_mode && mem) { perform_taint_run(afl, q, fname, mem, len); diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 058f8c2d..5f928333 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -349,7 +349,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, } - if (unlikely(afl->fsrv.taint_mode)) + if (unlikely(afl->taint_mode)) q->exec_cksum = 0; else if (q->exec_cksum) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e6238366..bead2ed9 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -288,7 +288,7 @@ int main(int argc, char **argv_orig, char **envp) { switch (opt) { case 'A': - afl->fsrv.taint_mode = 1; + afl->taint_mode = 1; if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_QEMU; } break; @@ -829,10 +829,10 @@ int main(int argc, char **argv_orig, char **envp) { } - if (afl->fsrv.taint_mode && afl->fsrv.map_size < MAX_FILE) { + if (afl->taint_mode && afl->fsrv.map_size < MAX_FILE) { real_map_size = map_size; - map_size = afl->fsrv.map_size = afl->shm.map_size = MAX_FILE; + map_size = MAX_FILE; } @@ -891,9 +891,12 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->crash_mode) { FATAL("-C and -n are mutually exclusive"); } if (afl->fsrv.qemu_mode) { FATAL("-Q and -n are mutually exclusive"); } if (afl->unicorn_mode) { FATAL("-U and -n are mutually exclusive"); } - if (afl->fsrv.taint_mode) { FATAL("-A and -n are mutually exclusive"); } + if (afl->taint_mode) { FATAL("-A and -n are mutually exclusive"); } } + + if (afl->limit_time_sig != 0 && afl->taint_mode) { FATAL("-A and -L are mutually exclusive"); } + if (afl->unicorn_mode != 0 && afl->taint_mode) { FATAL("-A and -U are mutually exclusive"); } if (get_afl_env("AFL_DISABLE_TRIM")) { afl->disable_trim = 1; } @@ -992,7 +995,7 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->afl_env.afl_preload) { - if (afl->fsrv.qemu_mode || afl->fsrv.taint_mode) { + if (afl->fsrv.qemu_mode || afl->taint_mode) { u8 *qemu_preload = getenv("QEMU_SET_ENV"); u8 *afl_preload = getenv("AFL_PRELOAD"); @@ -1088,17 +1091,17 @@ int main(int argc, char **argv_orig, char **envp) { afl->fsrv.trace_bits = afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode); - if (!afl->in_bitmap) { memset(afl->virgin_bits, 255, afl->fsrv.map_size); } - memset(afl->virgin_tmout, 255, afl->fsrv.map_size); - memset(afl->virgin_crash, 255, afl->fsrv.map_size); - - if (map_size != real_map_size) { + if (real_map_size && map_size != real_map_size) { afl->fsrv.map_size = real_map_size; if (afl->cmplog_binary) afl->cmplog_fsrv.map_size = real_map_size; } + if (!afl->in_bitmap) { memset(afl->virgin_bits, 255, afl->fsrv.map_size); } + memset(afl->virgin_tmout, 255, afl->fsrv.map_size); + memset(afl->virgin_crash, 255, afl->fsrv.map_size); + init_count_class16(); if (afl->is_main_node && check_main_node_exists(afl) == 1) { @@ -1260,7 +1263,7 @@ int main(int argc, char **argv_orig, char **envp) { } - if (afl->fsrv.taint_mode) { + if (afl->taint_mode) { ACTF("Spawning qemu_taint forkserver"); @@ -1268,7 +1271,6 @@ int main(int argc, char **argv_orig, char **envp) { setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); afl_fsrv_init_dup(&afl->taint_fsrv, &afl->fsrv); - afl->taint_fsrv.qemu_mode = 2; afl->taint_fsrv.taint_mode = 1; afl->taint_fsrv.trace_bits = afl->fsrv.trace_bits; @@ -1399,7 +1401,7 @@ int main(int argc, char **argv_orig, char **envp) { break; case 1: if (afl->limit_time_sig == 0 && !afl->custom_only && - !afl->python_only && !afl->fsrv.taint_mode) { + !afl->python_only && !afl->taint_mode) { afl->limit_time_sig = -1; afl->limit_time_puppet = 0; @@ -1588,7 +1590,7 @@ stop_fuzzing: } if (afl->cmplog_binary) afl_fsrv_deinit(&afl->cmplog_fsrv); - if (afl->fsrv.taint_mode) afl_fsrv_deinit(&afl->taint_fsrv); + if (afl->taint_mode) afl_fsrv_deinit(&afl->taint_fsrv); afl_fsrv_deinit(&afl->fsrv); if (afl->orig_cmdline) { ck_free(afl->orig_cmdline); } if (afl->argv_taint) { ck_free(afl->argv_taint); } -- cgit v1.2.3 From 220dc4a43d197f5ff451627a9923b874805c02aa Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 11 Aug 2020 16:25:35 +0200 Subject: review done, pray --- src/afl-fuzz-init.c | 3 +- src/afl-fuzz-one.c | 152 ++++++++++++++++++++++++++++++++++++++++----------- src/afl-fuzz-queue.c | 6 +- src/afl-fuzz-run.c | 10 +++- src/afl-fuzz.c | 17 ++++-- 5 files changed, 142 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 669bd65a..0150e18a 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -961,8 +961,7 @@ void perform_dry_run(afl_state_t *afl) { } /* perform taint gathering on the input seed */ - if (afl->taint_mode) - perform_taint_run(afl, q, q->fname, use_mem, q->len); + if (afl->taint_mode) perform_taint_run(afl, q, q->fname, use_mem, q->len); q = q->next; diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 69f885ca..7718256f 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -462,18 +462,23 @@ u8 fuzz_one_original(afl_state_t *afl) { if (unlikely(afl->taint_mode)) { - tmp_val = afl->queue_cycle % 2; + tmp_val = afl->queue_cycle % 2; // starts with 1 ret_val = 0; - if (unlikely(afl->queue_cur->cal_failed)) goto abandon_entry; - if (unlikely(!afl->queue_cur->passed_det) && !tmp_val) goto abandon_entry; - if (tmp_val == 1 && !afl->queue_cur->taint_bytes_all) goto abandon_entry; - if (tmp_val == 0 && !afl->queue_cur->taint_bytes_new) goto abandon_entry; + if (unlikely(afl->queue_cur->cal_failed && !tmp_val)) goto abandon_entry; + if (unlikely(!afl->skip_deterministic && !afl->queue_cur->passed_det && + !tmp_val)) + goto abandon_entry; + if ((!afl->queue_cur->taint_bytes_new || + afl->queue_cur->taint_bytes_new == afl->queue_cur->len) && + !tmp_val) + goto abandon_entry; ret_val = 1; s32 dst = 0, i; temp_len = len = afl->queue_cur->len; + s32 j = 0; // tmp fd = open(afl->queue_cur->fname, O_RDONLY); afl->taint_src = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); @@ -486,15 +491,27 @@ u8 fuzz_one_original(afl_state_t *afl) { case 1: // fuzz only tainted bytes + // special case: all or nothing tainted. in this case we act like + // nothing is special. this is not the taint you are looking for ... + if (!afl->queue_cur->taint_bytes_all || + afl->queue_cur->taint_bytes_all == (u32)len) { + + orig_in = in_buf = afl->taint_src; + afl->taint_needs_splode = 0; + break; + + } + fd = open(afl->taint_input_file, O_RDONLY); temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_all; orig_in = in_buf = - mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + mmap(0, len >= MAX_FILE - 65536 ? MAX_FILE : len + 65536, + PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (fd < 0 || (ssize_t)in_buf == -1) FATAL("unable to open '%s'", afl->taint_input_file); close(fd); - fd = open(afl->queue_cur->fname_taint, O_RDWR); + fd = open(afl->queue_cur->fname_taint, O_RDONLY); afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (fd < 0 || (ssize_t)in_buf == -1) @@ -504,6 +521,29 @@ u8 fuzz_one_original(afl_state_t *afl) { for (i = 0; i < (s32)afl->queue_cur->len && dst < len; i++) if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i]; + // FIXME DEBUG TODO XXX + for (i = 0; i < (s32)afl->queue_cur->len; i++) { + + switch (afl->taint_map[i]) { + + case 0x0: + break; + case '!': + j++; + break; + default: + FATAL( + "invalid taint map entry byte 0x%02x at position %d " + "(passed_det:%d)\n", + afl->taint_map[i], i, afl->queue_cur->passed_det); + + } + + } + + if (j != len) + FATAL("different taint values in map vs in queue (%d != %d)", j, len); + break; case 0: // fuzz only newly tainted bytes @@ -511,12 +551,14 @@ u8 fuzz_one_original(afl_state_t *afl) { fd = open(afl->taint_input_file, O_RDONLY); temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_new; orig_in = in_buf = - mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + mmap(0, len >= MAX_FILE - 65536 ? MAX_FILE : len + 65536, + PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (fd < 0 || (ssize_t)in_buf == -1) FATAL("unable to open '%s'", afl->taint_input_file); close(fd); u8 *fn = alloc_printf("%s.new", afl->queue_cur->fname_taint); + if (!fn) FATAL("OOM"); fd = open(fn, O_RDWR); afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); @@ -528,14 +570,35 @@ u8 fuzz_one_original(afl_state_t *afl) { for (i = 0; i < (s32)afl->queue_cur->len && dst < len; i++) if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i]; + // FIXME DEBUG TODO XXX + for (i = 0; i < (s32)afl->queue_cur->len; i++) { + + switch (afl->taint_map[i]) { + + case 0x0: + break; + case '!': + j++; + break; + default: + FATAL( + "invalid taint map entry byte 0x%02x at position %d " + "(passed_det:%d)\n", + afl->taint_map[i], i, afl->queue_cur->passed_det); + + } + + } + + if (j != len) + FATAL("different taint values in map vs in queue (%d != %d)", j, len); + break; } } else { - afl->taint_needs_splode = 0; - /* Map the test case into memory. */ fd = open(afl->queue_cur->fname, O_RDONLY); @@ -574,8 +637,7 @@ u8 fuzz_one_original(afl_state_t *afl) { * CALIBRATION (only if failed earlier on) * *******************************************/ - if (unlikely(afl->queue_cur->cal_failed && - (!afl->taint_needs_splode || tmp_val == 1))) { + if (unlikely(afl->queue_cur->cal_failed)) { u8 res = FSRV_RUN_TMOUT; @@ -583,8 +645,12 @@ u8 fuzz_one_original(afl_state_t *afl) { afl->queue_cur->exec_cksum = 0; - res = - calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0); + if (unlikely(afl->taint_needs_splode)) + res = calibrate_case(afl, afl->queue_cur, afl->taint_src, + afl->queue_cycle - 1, 0); + else + res = calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, + 0); if (unlikely(res == FSRV_RUN_ERROR)) { @@ -607,8 +673,8 @@ u8 fuzz_one_original(afl_state_t *afl) { * TRIMMING * ************/ - if (!afl->non_instrumented_mode && !afl->queue_cur->trim_done && - !afl->disable_trim && !afl->taint_needs_splode) { + if (unlikely(!afl->non_instrumented_mode && !afl->queue_cur->trim_done && + !afl->disable_trim && !afl->taint_needs_splode)) { u8 res = trim_case(afl, afl->queue_cur, in_buf); @@ -645,13 +711,26 @@ u8 fuzz_one_original(afl_state_t *afl) { if (afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized) { - if (input_to_state_stage(afl, in_buf, out_buf, len, - afl->queue_cur->exec_cksum)) { + int res; + if (unlikely(afl->taint_needs_splode)) { - goto abandon_entry; + len = afl->queue_cur->len; + memcpy(out_buf, afl->taint_src, len); + res = input_to_state_stage(afl, afl->taint_src, out_buf, len, + afl->queue_cur->exec_cksum); + // just abandon as success + ret_val = 0; + res = 1; + + } else { + + res = input_to_state_stage(afl, in_buf, out_buf, len, + afl->queue_cur->exec_cksum); } + if (unlikely(res)) { goto abandon_entry; } + } /* Skip right away if -d is given, if it has not been chosen sufficiently @@ -2288,37 +2367,46 @@ havoc_stage: copy_len = choose_block_len(afl, afl->queue_cur->len - 1); copy_from = rand_below(afl, afl->queue_cur->len - copy_len + 1); + copy_to = rand_below(afl, temp_len + 1); } else { copy_len = choose_block_len(afl, temp_len - 1); copy_from = rand_below(afl, temp_len - copy_len + 1); + copy_to = rand_below(afl, temp_len - copy_len + 1); } - copy_to = rand_below(afl, temp_len - copy_len + 1); - if (unlikely(copy_to > (u32)temp_len)) - copy_to = rand_below(afl, temp_len); - if (rand_below(afl, 4)) { if (copy_from != copy_to) { if (unlikely(afl->taint_needs_splode)) { - if (copy_to > (u32)temp_len) - copy_to = rand_below(afl, temp_len); + if (temp_len >= (s32)(copy_to + copy_len)) { - // fprintf(stderr, "\nout_buf %p + copy_to %u, src %p + %u, - // copy_len %u -- len %u\n", out_buf , copy_to, afl->taint_src , - // copy_from, copy_len, afl->taint_len, afl->queue_cur->len); - memmove(out_buf + copy_to, afl->taint_src + copy_from, - copy_len); + memcpy(out_buf + copy_to, afl->taint_src + copy_from, + copy_len); - } else + } else { + + u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), + copy_to + copy_len); + memcpy(new_buf, in_buf, copy_to); + memcpy(new_buf + copy_to, afl->taint_src + copy_from, + copy_len); + swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); + out_buf = new_buf; + temp_len = copy_to + copy_len; + + } + + } else { memmove(out_buf + copy_to, out_buf + copy_from, copy_len); + } + } } else { @@ -2698,7 +2786,7 @@ abandon_entry: ++afl->queue_cur->fuzz_level; - if (afl->taint_needs_splode) { + if (unlikely(afl->taint_needs_splode)) { munmap(afl->taint_src, afl->queue_cur->len); munmap(orig_in, afl->taint_len); diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index bb44e465..a1fe146b 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -420,11 +420,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u8 *mem, u32 len, afl->last_path_time = get_cur_time(); /* trigger the tain gathering if this is not a dry run */ - if (afl->taint_mode && mem) { - - perform_taint_run(afl, q, fname, mem, len); - - } + if (afl->taint_mode && mem) { perform_taint_run(afl, q, fname, mem, len); } /* only redqueen currently uses is_ascii */ if (afl->shm.cmplog_mode) q->is_ascii = check_if_text(q); diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 5f928333..94cfc383 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -878,9 +878,11 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { if (unlikely(afl->taint_needs_splode)) { s32 new_len = afl->queue_cur->len + len - afl->taint_len; - if (new_len < 4) new_len = 4; - if (new_len > MAX_FILE) new_len = MAX_FILE; - u8 *new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), new_len); + if (new_len < 4) + new_len = 4; + else if (new_len > MAX_FILE) + new_len = MAX_FILE; + u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), new_len); u32 i, taint = 0; for (i = 0; i < (u32)new_len; i++) { @@ -892,6 +894,8 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { } + swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); + out_buf = new_buf; len = new_len; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index bead2ed9..106aa550 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -894,9 +894,18 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->taint_mode) { FATAL("-A and -n are mutually exclusive"); } } - - if (afl->limit_time_sig != 0 && afl->taint_mode) { FATAL("-A and -L are mutually exclusive"); } - if (afl->unicorn_mode != 0 && afl->taint_mode) { FATAL("-A and -U are mutually exclusive"); } + + if (afl->limit_time_sig != 0 && afl->taint_mode) { + + FATAL("-A and -L are mutually exclusive"); + + } + + if (afl->unicorn_mode != 0 && afl->taint_mode) { + + FATAL("-A and -U are mutually exclusive"); + + } if (get_afl_env("AFL_DISABLE_TRIM")) { afl->disable_trim = 1; } @@ -1309,7 +1318,7 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Taint forkserver successfully started"); - const rlim_t kStackSize = 256L * 1024L * 1024L; // min stack size = 256 Mb + const rlim_t kStackSize = 128L * 1024L * 1024L; // min stack size = 128 Mb struct rlimit rl; rl.rlim_cur = kStackSize; if (getrlimit(RLIMIT_STACK, &rl) != 0) -- cgit v1.2.3 From b604f5eafcebb816026e198df0ea66ebcbf18421 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 11 Aug 2020 18:06:18 +0200 Subject: finalize first beta! yay! --- src/afl-fuzz-init.c | 9 +++++++-- src/afl-fuzz-one.c | 2 +- src/afl-fuzz-queue.c | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 0150e18a..359eef85 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -771,9 +771,13 @@ void perform_dry_run(afl_state_t *afl) { close(fd); res = calibrate_case(afl, q, use_mem, 0, 1); - ck_free(use_mem); - if (afl->stop_soon) { return; } + if (afl->stop_soon) { + + ck_free(use_mem); + return; + + } if (res == afl->crash_mode || res == FSRV_RUN_NOBITS) { @@ -962,6 +966,7 @@ void perform_dry_run(afl_state_t *afl) { /* perform taint gathering on the input seed */ if (afl->taint_mode) perform_taint_run(afl, q, q->fname, use_mem, q->len); + ck_free(use_mem); q = q->next; diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 7718256f..4db6febf 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2342,7 +2342,7 @@ havoc_stage: } /* Tail */ - memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, + memmove(new_buf + clone_to + clone_len, out_buf + clone_to, temp_len - clone_to); swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index a1fe146b..43794018 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -122,7 +122,7 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname, afl->taint_fsrv.map_size = plen; // speed :) write_to_testcase(afl, mem, len); - if (afl_fsrv_run_target(&afl->taint_fsrv, afl->fsrv.exec_tmout, + if (afl_fsrv_run_target(&afl->taint_fsrv, afl->fsrv.exec_tmout * 4, &afl->stop_soon) == 0) { bytes = q->taint_bytes_all = -- cgit v1.2.3 From b38837f4ff8f2e52597b7908b9226500e5c61933 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 12 Aug 2020 14:14:44 +0200 Subject: setting attribute hot intelligently gives 0.5% speed --- src/afl-forkserver.c | 4 ++-- src/afl-fuzz-bitmap.c | 8 ++++---- src/afl-fuzz-run.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 1ececf27..6819fc8a 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -122,7 +122,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { Returns the time passed to read. If the wait times out, returns timeout_ms + 1; Returns 0 if an error occurred (fd closed, signal, ...); */ -static u32 read_s32_timed(s32 fd, s32 *buf, u32 timeout_ms, +static u32 __attribute__ ((hot)) read_s32_timed(s32 fd, s32 *buf, u32 timeout_ms, volatile u8 *stop_soon_p) { fd_set readfds; @@ -322,7 +322,7 @@ static void report_error_and_exit(int error) { cloning a stopped child. So, we just execute once, and then send commands through a pipe. The other part of this logic is in afl-as.h / llvm_mode */ -void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, +void __attribute__ ((hot)) 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]; diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index aa8d5a18..f6389c06 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -57,7 +57,7 @@ void write_bitmap(afl_state_t *afl) { This function is called after every exec() on a fairly large buffer, so it needs to be fast. We do this in 32-bit and 64-bit flavors. */ -u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) { +u8 __attribute__ ((hot)) has_new_bits(afl_state_t *afl, u8 *virgin_map) { #ifdef WORD_SIZE_64 @@ -347,7 +347,7 @@ void init_count_class16(void) { #ifdef WORD_SIZE_64 -void classify_counts(afl_forkserver_t *fsrv) { +void __attribute__ ((hot)) classify_counts(afl_forkserver_t *fsrv) { u64 *mem = (u64 *)fsrv->trace_bits; @@ -376,7 +376,7 @@ void classify_counts(afl_forkserver_t *fsrv) { #else -void classify_counts(afl_forkserver_t *fsrv) { +void __attribute__ ((hot)) classify_counts(afl_forkserver_t *fsrv) { u32 *mem = (u32 *)fsrv->trace_bits; @@ -534,7 +534,7 @@ static void write_crash_readme(afl_state_t *afl) { save or queue the input test case for further analysis if so. Returns 1 if entry is saved, 0 otherwise. */ -u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { +u8 __attribute__ ((hot)) save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (unlikely(len == 0)) { return 0; } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index e69e9791..97fcb3c8 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -38,7 +38,7 @@ u64 time_spent_working = 0; /* Execute target application, monitoring for timeouts. Return status information. The called program will update afl->fsrv->trace_bits. */ -fsrv_run_result_t fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, +fsrv_run_result_t __attribute__ ((hot)) fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, u32 timeout) { #ifdef PROFILING @@ -72,7 +72,7 @@ fsrv_run_result_t fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, old file is unlinked and a new one is created. Otherwise, afl->fsrv.out_fd is rewound and truncated. */ -void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { +void __attribute__ ((hot)) write_to_testcase(afl_state_t *afl, void *mem, u32 len) { #ifdef _AFL_DOCUMENT_MUTATIONS s32 doc_fd; @@ -858,7 +858,7 @@ abort_trimming: error conditions, returning 1 if it's time to bail out. This is a helper function for fuzz_one(). */ -u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { +u8 __attribute__ ((hot)) common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { u8 fault; -- cgit v1.2.3 From 7a6867e2f8e8b698c08366f79d0c8751b09ce431 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 12 Aug 2020 16:06:30 +0200 Subject: split up __afl_manual_init, added internal AFL_DISABLE_LLVM_INSTRUMENTATION, skipping ctor+ifunc functions for all llvm, code-format --- src/afl-forkserver.c | 11 +++++++---- src/afl-fuzz-bitmap.c | 9 +++++---- src/afl-fuzz-run.c | 10 ++++++---- 3 files changed, 18 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 6819fc8a..8684bcc0 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -58,6 +58,8 @@ static list_t fsrv_list = {.element_prealloc_count = 0}; static void fsrv_exec_child(afl_forkserver_t *fsrv, char **argv) { + if (fsrv->qemu_mode) setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); + execv(fsrv->target_path, argv); } @@ -122,8 +124,8 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { Returns the time passed to read. If the wait times out, returns timeout_ms + 1; Returns 0 if an error occurred (fd closed, signal, ...); */ -static u32 __attribute__ ((hot)) read_s32_timed(s32 fd, s32 *buf, u32 timeout_ms, - volatile u8 *stop_soon_p) { +static u32 __attribute__((hot)) +read_s32_timed(s32 fd, s32 *buf, u32 timeout_ms, volatile u8 *stop_soon_p) { fd_set readfds; FD_ZERO(&readfds); @@ -322,8 +324,9 @@ static void report_error_and_exit(int error) { cloning a stopped child. So, we just execute once, and then send commands through a pipe. The other part of this logic is in afl-as.h / llvm_mode */ -void __attribute__ ((hot)) afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, - volatile u8 *stop_soon_p, u8 debug_child_output) { +void __attribute__((hot)) +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; diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index f6389c06..1b9df624 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -57,7 +57,7 @@ void write_bitmap(afl_state_t *afl) { This function is called after every exec() on a fairly large buffer, so it needs to be fast. We do this in 32-bit and 64-bit flavors. */ -u8 __attribute__ ((hot)) has_new_bits(afl_state_t *afl, u8 *virgin_map) { +u8 __attribute__((hot)) has_new_bits(afl_state_t *afl, u8 *virgin_map) { #ifdef WORD_SIZE_64 @@ -347,7 +347,7 @@ void init_count_class16(void) { #ifdef WORD_SIZE_64 -void __attribute__ ((hot)) classify_counts(afl_forkserver_t *fsrv) { +void __attribute__((hot)) classify_counts(afl_forkserver_t *fsrv) { u64 *mem = (u64 *)fsrv->trace_bits; @@ -376,7 +376,7 @@ void __attribute__ ((hot)) classify_counts(afl_forkserver_t *fsrv) { #else -void __attribute__ ((hot)) classify_counts(afl_forkserver_t *fsrv) { +void __attribute__((hot)) classify_counts(afl_forkserver_t *fsrv) { u32 *mem = (u32 *)fsrv->trace_bits; @@ -534,7 +534,8 @@ static void write_crash_readme(afl_state_t *afl) { save or queue the input test case for further analysis if so. Returns 1 if entry is saved, 0 otherwise. */ -u8 __attribute__ ((hot)) save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { +u8 __attribute__((hot)) +save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (unlikely(len == 0)) { return 0; } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 97fcb3c8..d3f823c9 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -38,8 +38,8 @@ u64 time_spent_working = 0; /* Execute target application, monitoring for timeouts. Return status information. The called program will update afl->fsrv->trace_bits. */ -fsrv_run_result_t __attribute__ ((hot)) fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, - u32 timeout) { +fsrv_run_result_t __attribute__((hot)) +fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, u32 timeout) { #ifdef PROFILING static u64 time_spent_start = 0; @@ -72,7 +72,8 @@ fsrv_run_result_t __attribute__ ((hot)) fuzz_run_target(afl_state_t *afl, afl_fo old file is unlinked and a new one is created. Otherwise, afl->fsrv.out_fd is rewound and truncated. */ -void __attribute__ ((hot)) write_to_testcase(afl_state_t *afl, void *mem, u32 len) { +void __attribute__((hot)) +write_to_testcase(afl_state_t *afl, void *mem, u32 len) { #ifdef _AFL_DOCUMENT_MUTATIONS s32 doc_fd; @@ -858,7 +859,8 @@ abort_trimming: error conditions, returning 1 if it's time to bail out. This is a helper function for fuzz_one(). */ -u8 __attribute__ ((hot)) common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { +u8 __attribute__((hot)) +common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { u8 fault; -- cgit v1.2.3 From 2c5e103278c3266c15226f097e8e9e15267c57d6 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 13 Aug 2020 12:39:18 +0200 Subject: make cmplog deterministic --- src/afl-fuzz-redqueen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 9716be95..4309098a 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -151,7 +151,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) { /* Discard if the mutations change the paths or if it is too decremental in speed */ if (cksum != exec_cksum || - (stop_us - start_us > 2 * afl->queue_cur->exec_us)) { + (stop_us - start_us > 2 * afl->queue_cur->exec_us) && likely(!afl->fixed_seed)) { ranges = add_range(ranges, rng->start, rng->start + s / 2); ranges = add_range(ranges, rng->start + s / 2 + 1, rng->end); -- cgit v1.2.3 From c4e52e20c9fa41b95e110d288bc96939e5625761 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 13 Aug 2020 12:58:10 +0200 Subject: fix warning --- src/afl-fuzz-redqueen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 4309098a..4c0c9155 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -151,7 +151,8 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) { /* Discard if the mutations change the paths or if it is too decremental in speed */ if (cksum != exec_cksum || - (stop_us - start_us > 2 * afl->queue_cur->exec_us) && likely(!afl->fixed_seed)) { + ((stop_us - start_us > 2 * afl->queue_cur->exec_us) && + likely(!afl->fixed_seed))) { ranges = add_range(ranges, rng->start, rng->start + s / 2); ranges = add_range(ranges, rng->start + s / 2 + 1, rng->end); -- cgit v1.2.3 From 212bb990b7579831baad70735b767dbaf89e9e89 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 13 Aug 2020 21:27:11 +0200 Subject: LTO: apply laf-intel+redqueen/cmplog at link time --- src/afl-showmap.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 91 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 0aa116e5..fa9eedc4 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -68,9 +68,11 @@ static char *stdin_file; /* stdin file */ static u8 *in_dir = NULL, /* input folder */ *out_file = NULL, *at_file = NULL; /* Substitution string for @@ */ -static u8 *in_data; /* Input data */ +static u8 *in_data, /* Input data */ + *coverage_map; /* Coverage map */ -static u32 total, highest; /* tuple content information */ +static u64 total; /* tuple content information */ +static u32 tcnt, highest; /* tuple content information */ static u32 in_len, /* Input data length */ arg_offset; /* Total number of execs */ @@ -83,7 +85,8 @@ static u8 quiet_mode, /* Hide non-essential messages? */ cmin_mode, /* Generate output in afl-cmin mode? */ binary_mode, /* Write output as a binary map */ keep_cores, /* Allow coredumps? */ - remove_shm = 1; /* remove shmem? */ + remove_shm = 1, /* remove shmem? */ + collect_coverage; /* collect coverage */ static volatile u8 stop_soon, /* Ctrl-C pressed? */ child_crashed; /* Child crashed? */ @@ -175,6 +178,25 @@ static void at_exit_handler(void) { } +/* Analyze results. */ + +static void analyze_results(afl_forkserver_t *fsrv) { + + u32 i; + for (i = 0; i < map_size; i++) { + + if (fsrv->trace_bits[i]) { + + total += fsrv->trace_bits[i]; + if (fsrv->trace_bits[i] > highest) highest = fsrv->trace_bits[i]; + if (!coverage_map[i]) { coverage_map[i] = 1; } + + } + + } + +} + /* Write results. */ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { @@ -588,9 +610,14 @@ static void usage(u8 *argv0) { " (Not necessary, here for consistency with other afl-* " "tools)\n\n" "Other settings:\n" - " -i dir - process all files in this directory, -o must be a " + " -i dir - process all files in this directory, must be combined " + "with -o.\n" + " With -C, -o is a file, without -C it must be a " "directory\n" " and each bitmap will be written there individually.\n" + " -C - collect coverage, writes all edges to -o and gives a " + "summary\n" + " Must be combined with -i.\n" " -q - sink program's output and don't show messages\n" " -e - show edge coverage only, ignore hit counts\n" " -r - show real tuple values instead of AFL filter values\n" @@ -624,7 +651,6 @@ int main(int argc, char **argv_orig, char **envp) { s32 opt, i; u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0; - u32 tcnt = 0; char **use_argv; char **argv = argv_cpy_dup(argc, argv_orig); @@ -639,10 +665,14 @@ int main(int argc, char **argv_orig, char **envp) { if (getenv("AFL_QUIET") != NULL) { be_quiet = 1; } - while ((opt = getopt(argc, argv, "+i:o:f:m:t:A:eqZQUWbcrh")) > 0) { + while ((opt = getopt(argc, argv, "+i:o:f:m:t:A:eqCZQUWbcrh")) > 0) { switch (opt) { + case 'C': + collect_coverage = 1; + break; + case 'i': if (in_dir) { FATAL("Multiple -i options not supported"); } in_dir = optarg; @@ -820,6 +850,13 @@ int main(int argc, char **argv_orig, char **envp) { if (optind == argc || !out_file) { usage(argv[0]); } + if (in_dir) { + + if (!out_file && !collect_coverage) + FATAL("for -i you need to specify either -C and/or -o"); + + } + if (fsrv->qemu_mode && !mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_QEMU; } if (unicorn_mode && !mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_UNICORN; } @@ -910,7 +947,7 @@ int main(int argc, char **argv_orig, char **envp) { if (in_dir) { - DIR * dir_in, *dir_out; + DIR * dir_in, *dir_out = NULL; struct dirent *dir_ent; int done = 0; u8 infile[PATH_MAX], outfile[PATH_MAX]; @@ -924,20 +961,43 @@ int main(int argc, char **argv_orig, char **envp) { fsrv->dev_null_fd = open("/dev/null", O_RDWR); if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); } + // if a queue subdirectory exists switch to that + u8 *dn = alloc_printf("%s/queue", in_dir); + if ((dir_in = opendir(in_dir))) { + + closedir(dir_in); + in_dir = dn; + + } else + + ck_free(dn); + if (!be_quiet) ACTF("Reading from directory '%s'...", in_dir); + if (!(dir_in = opendir(in_dir))) { PFATAL("cannot open directory %s", in_dir); } - if (!(dir_out = opendir(out_file))) { + if (!collect_coverage) { + + if (!(dir_out = opendir(out_file))) { + + if (mkdir(out_file, 0700)) { - if (mkdir(out_file, 0700)) { + PFATAL("cannot create output directory %s", out_file); - PFATAL("cannot create output directory %s", out_file); + } } + } else { + + if ((coverage_map = (u8 *)malloc(map_size)) == NULL) + FATAL("coult not grab memory"); + edges_only = 0; + raw_instr_output = 1; + } u8 *use_dir = "."; @@ -978,6 +1038,7 @@ int main(int argc, char **argv_orig, char **envp) { afl_fsrv_start(fsrv, use_argv, &stop_soon, get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0); + map_size = fsrv->map_size; if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz); @@ -1005,7 +1066,8 @@ int main(int argc, char **argv_orig, char **envp) { if (-1 == stat(infile, &statbuf) || !S_ISREG(statbuf.st_mode)) continue; #endif - snprintf(outfile, sizeof(outfile), "%s/%s", out_file, dir_ent->d_name); + if (!collect_coverage) + snprintf(outfile, sizeof(outfile), "%s/%s", out_file, dir_ent->d_name); if (read_file(infile)) { @@ -1019,7 +1081,10 @@ int main(int argc, char **argv_orig, char **envp) { showmap_run_target_forkserver(fsrv, in_data, in_len); ck_free(in_data); - tcnt = write_results_to_file(fsrv, outfile); + if (collect_coverage) + analyze_results(fsrv); + else + tcnt = write_results_to_file(fsrv, outfile); } @@ -1030,6 +1095,13 @@ int main(int argc, char **argv_orig, char **envp) { closedir(dir_in); if (dir_out) { closedir(dir_out); } + if (collect_coverage) { + + memcpy(fsrv->trace_bits, coverage_map, map_size); + tcnt = write_results_to_file(fsrv, out_file); + + } + } else { if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz) @@ -1043,8 +1115,14 @@ int main(int argc, char **argv_orig, char **envp) { if (!quiet_mode) { if (!tcnt) { FATAL("No instrumentation detected" cRST); } - OKF("Captured %u tuples (highest value %u, total values %u) in '%s'." cRST, + OKF("Captured %u tuples (highest value %u, total values %llu) in " + "'%s'." cRST, tcnt, highest, total, out_file); + if (collect_coverage) + OKF("A coverage of %u edges were achieved out of %u existing (%.02f%%) " + "with %llu input files.", + tcnt, map_size, ((float)tcnt * 100) / (float)map_size, + fsrv->total_execs); } -- cgit v1.2.3 From b5d1a021efaede5e084418fe552330590ee43641 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 13 Aug 2020 22:34:11 +0200 Subject: fix llvm and afl-showmap --- src/afl-showmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index fa9eedc4..47c615d8 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -963,7 +963,7 @@ int main(int argc, char **argv_orig, char **envp) { // if a queue subdirectory exists switch to that u8 *dn = alloc_printf("%s/queue", in_dir); - if ((dir_in = opendir(in_dir))) { + if ((dir_in = opendir(dn)) != NULL) { closedir(dir_in); in_dir = dn; -- cgit v1.2.3 From 83df65a66b8df37d0759bf9b31a61f50234d6c40 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 14 Aug 2020 00:46:15 +0200 Subject: cleaned up maybe_add_auto calls --- src/afl-forkserver.c | 28 +++++++++++++++++++--------- src/afl-fuzz-extras.c | 8 ++------ src/afl-fuzz-one.c | 8 ++++---- src/afl-fuzz-redqueen.c | 12 ++++++------ src/afl-fuzz-state.c | 5 +++-- 5 files changed, 34 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 8684bcc0..01fc829a 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -324,8 +324,7 @@ static void report_error_and_exit(int error) { cloning a stopped child. So, we just execute once, and then send commands through a pipe. The other part of this logic is in afl-as.h / llvm_mode */ -void __attribute__((hot)) -afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, volatile u8 *stop_soon_p, +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]; @@ -631,13 +630,18 @@ afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, volatile u8 *stop_soon_p, if ((status & FS_OPT_AUTODICT) == FS_OPT_AUTODICT) { - if (fsrv->function_ptr == NULL || fsrv->function_opt == NULL) { + if (fsrv->autodict_func == NULL || fsrv->afl_ptr == NULL) { // this is not afl-fuzz - we deny and return - if (fsrv->use_shmem_fuzz) + if (fsrv->use_shmem_fuzz) { + status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ); - else + + } else { + status = (FS_OPT_ENABLED); + + } if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) { FATAL("Writing to forkserver failed."); @@ -650,11 +654,16 @@ afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, volatile u8 *stop_soon_p, if (!be_quiet) { ACTF("Using AUTODICT feature."); } - if (fsrv->use_shmem_fuzz) + if (fsrv->use_shmem_fuzz) { + status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ); - else + + } else { + status = (FS_OPT_ENABLED | FS_OPT_AUTODICT); + } + if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) { FATAL("Writing to forkserver failed."); @@ -673,7 +682,8 @@ afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, volatile u8 *stop_soon_p, } - u32 len = status, offset = 0, count = 0; + u32 offset = 0, count = 0; + u32 len = status; u8 *dict = ck_alloc(len); if (dict == NULL) { @@ -704,7 +714,7 @@ afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, volatile u8 *stop_soon_p, while (offset < (u32)status && (u8)dict[offset] + offset < (u32)status) { - fsrv->function_ptr(fsrv->function_opt, dict + offset + 1, + fsrv->autodict_func(fsrv->afl_ptr, dict + offset + 1, (u8)dict[offset]); offset += (1 + dict[offset]); count++; diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 097871c8..2f3a2d53 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -354,13 +354,9 @@ static inline u8 memcmp_nocase(u8 *m1, u8 *m2, u32 len) { } /* Maybe add automatic extra. */ -/* Ugly hack: afl state is transfered as u8* because we import data via - afl-forkserver.c - which is shared with other afl tools that do not - have the afl state struct */ -void maybe_add_auto(void *afl_tmp, u8 *mem, u32 len) { +void maybe_add_auto(afl_state_t *afl, u8 *mem, u32 len) { - afl_state_t *afl = (afl_state_t *)afl_tmp; u32 i; /* Allow users to specify that they don't want auto dictionaries. */ @@ -544,7 +540,7 @@ void load_auto(afl_state_t *afl) { if (len >= MIN_AUTO_EXTRA && len <= MAX_AUTO_EXTRA) { - maybe_add_auto((u8 *)afl, tmp, len); + maybe_add_auto(afl, tmp, len); } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 452c5298..57b53c9f 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -681,7 +681,7 @@ u8 fuzz_one_original(afl_state_t *afl) { if (a_len >= MIN_AUTO_EXTRA && a_len <= MAX_AUTO_EXTRA) { - maybe_add_auto((u8 *)afl, a_collect, a_len); + maybe_add_auto(afl, a_collect, a_len); } @@ -692,7 +692,7 @@ u8 fuzz_one_original(afl_state_t *afl) { if (a_len >= MIN_AUTO_EXTRA && a_len <= MAX_AUTO_EXTRA) { - maybe_add_auto((u8 *)afl, a_collect, a_len); + maybe_add_auto(afl, a_collect, a_len); } @@ -2882,7 +2882,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { if (a_len >= MIN_AUTO_EXTRA && a_len <= MAX_AUTO_EXTRA) { - maybe_add_auto((u8 *)afl, a_collect, a_len); + maybe_add_auto(afl, a_collect, a_len); } @@ -2893,7 +2893,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { if (a_len >= MIN_AUTO_EXTRA && a_len <= MAX_AUTO_EXTRA) { - maybe_add_auto((u8 *)afl, a_collect, a_len); + maybe_add_auto(afl, a_collect, a_len); } diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 4c0c9155..f21dd0b0 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -500,7 +500,7 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { } - maybe_add_auto((u8 *)afl, (u8 *)&v, shape); + maybe_add_auto(afl, (u8 *)&v, shape); u64 rev; switch (shape) { @@ -509,15 +509,15 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { break; case 2: rev = SWAP16((u16)v); - maybe_add_auto((u8 *)afl, (u8 *)&rev, shape); + maybe_add_auto(afl, (u8 *)&rev, shape); break; case 4: rev = SWAP32((u32)v); - maybe_add_auto((u8 *)afl, (u8 *)&rev, shape); + maybe_add_auto(afl, (u8 *)&rev, shape); break; case 8: rev = SWAP64(v); - maybe_add_auto((u8 *)afl, (u8 *)&rev, shape); + maybe_add_auto(afl, (u8 *)&rev, shape); break; } @@ -772,8 +772,8 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { if (afl->pass_stats[key].total == 0) { - maybe_add_auto((u8 *)afl, o->v0, SHAPE_BYTES(h->shape)); - maybe_add_auto((u8 *)afl, o->v1, SHAPE_BYTES(h->shape)); + maybe_add_auto(afl, o->v0, SHAPE_BYTES(h->shape)); + maybe_add_auto(afl, o->v1, SHAPE_BYTES(h->shape)); } diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index e2d62bc6..97e4ee93 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -112,8 +112,9 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->fsrv.use_stdin = 1; afl->fsrv.map_size = map_size; - afl->fsrv.function_opt = (u8 *)afl; - afl->fsrv.function_ptr = &maybe_add_auto; + // afl_state_t is not available in forkserver.c + afl->fsrv.afl_ptr = (void *)afl; + afl->fsrv.autodict_func = (void (*)(void *, u8 *, u32))&maybe_add_auto; afl->cal_cycles = CAL_CYCLES; afl->cal_cycles_long = CAL_CYCLES_LONG; -- cgit v1.2.3 From 69f8c62955ecd494fb21c348511b2b7a0e012274 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 14 Aug 2020 00:46:48 +0200 Subject: code-format --- src/afl-forkserver.c | 9 +++++---- src/afl-fuzz-extras.c | 2 +- src/afl-fuzz-state.c | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 01fc829a..33dfde97 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -324,8 +324,8 @@ static void report_error_and_exit(int error) { cloning a stopped child. So, we just execute once, and then send commands through a pipe. The other part of this logic is in afl-as.h / llvm_mode */ -void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, volatile u8 *stop_soon_p, - u8 debug_child_output) { +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; @@ -642,6 +642,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, volatile u8 *stop_soon_ status = (FS_OPT_ENABLED); } + if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) { FATAL("Writing to forkserver failed."); @@ -658,7 +659,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, volatile u8 *stop_soon_ status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ); - } else { + } else { status = (FS_OPT_ENABLED | FS_OPT_AUTODICT); @@ -715,7 +716,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, volatile u8 *stop_soon_ (u8)dict[offset] + offset < (u32)status) { fsrv->autodict_func(fsrv->afl_ptr, dict + offset + 1, - (u8)dict[offset]); + (u8)dict[offset]); offset += (1 + dict[offset]); count++; diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 2f3a2d53..d678279d 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -357,7 +357,7 @@ static inline u8 memcmp_nocase(u8 *m1, u8 *m2, u32 len) { void maybe_add_auto(afl_state_t *afl, u8 *mem, u32 len) { - u32 i; + u32 i; /* Allow users to specify that they don't want auto dictionaries. */ diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 97e4ee93..d4de91a4 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -114,7 +114,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->fsrv.map_size = map_size; // afl_state_t is not available in forkserver.c afl->fsrv.afl_ptr = (void *)afl; - afl->fsrv.autodict_func = (void (*)(void *, u8 *, u32))&maybe_add_auto; + afl->fsrv.autodict_func = (void (*)(void *, u8 *, u32)) & maybe_add_auto; afl->cal_cycles = CAL_CYCLES; afl->cal_cycles_long = CAL_CYCLES_LONG; -- cgit v1.2.3 From d1bc0207cc6e579fe914dcbb0b70653783b64598 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 14 Aug 2020 01:33:03 +0200 Subject: no longer using alloc for autodict --- src/afl-fuzz-extras.c | 46 ++++++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index d678279d..94f50394 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -25,23 +25,26 @@ #include "afl-fuzz.h" -/* Helper function for load_extras. */ +/* helper function for auto_extras qsort */ +static int compare_auto_extras_len(const void *ae1, const void *ae2) { + + return ((struct auto_extra_data *)ae1)->len - ((struct auto_extra_data *)ae2)->len; + +} -static int compare_extras_len(const void *p1, const void *p2) { +/* descending order */ - struct extra_data *e1 = (struct extra_data *)p1, - *e2 = (struct extra_data *)p2; +static int compare_auto_extras_use_d(const void *ae1, const void *ae2) { - return e1->len - e2->len; + return ((struct auto_extra_data *)ae2)->hit_cnt - ((struct auto_extra_data *)ae1)->hit_cnt; } -static int compare_extras_use_d(const void *p1, const void *p2) { +/* Helper function for load_extras. */ - struct extra_data *e1 = (struct extra_data *)p1, - *e2 = (struct extra_data *)p2; +static int compare_extras_len(const void *e1, const void *e2) { - return e2->hit_cnt - e1->hit_cnt; + return ((struct extra_data *)e1)->len - ((struct extra_data *)e2)->len; } @@ -371,7 +374,7 @@ void maybe_add_auto(afl_state_t *afl, u8 *mem, u32 len) { } - if (i == len) { return; } + if (i == len || unlikely(len > MAX_AUTO_EXTRA)) { return; } /* Reject builtin interesting values. */ @@ -448,10 +451,7 @@ void maybe_add_auto(afl_state_t *afl, u8 *mem, u32 len) { if (afl->a_extras_cnt < MAX_AUTO_EXTRAS) { - afl->a_extras = ck_realloc_block( - afl->a_extras, (afl->a_extras_cnt + 1) * sizeof(struct extra_data)); - - afl->a_extras[afl->a_extras_cnt].data = ck_memdup(mem, len); + memcpy(afl->a_extras[afl->a_extras_cnt].data, mem, len); afl->a_extras[afl->a_extras_cnt].len = len; ++afl->a_extras_cnt; @@ -459,9 +459,7 @@ void maybe_add_auto(afl_state_t *afl, u8 *mem, u32 len) { i = MAX_AUTO_EXTRAS / 2 + rand_below(afl, (MAX_AUTO_EXTRAS + 1) / 2); - ck_free(afl->a_extras[i].data); - - afl->a_extras[i].data = ck_memdup(mem, len); + memcpy(afl->a_extras[i].data, mem, len); afl->a_extras[i].len = len; afl->a_extras[i].hit_cnt = 0; @@ -471,13 +469,13 @@ sort_a_extras: /* First, sort all auto extras by use count, descending order. */ - qsort(afl->a_extras, afl->a_extras_cnt, sizeof(struct extra_data), - compare_extras_use_d); + qsort(afl->a_extras, afl->a_extras_cnt, sizeof(struct auto_extra_data), + compare_auto_extras_use_d); /* Then, sort the top USE_AUTO_EXTRAS entries by size. */ qsort(afl->a_extras, MIN((u32)USE_AUTO_EXTRAS, afl->a_extras_cnt), - sizeof(struct extra_data), compare_extras_len); + sizeof(struct auto_extra_data), compare_auto_extras_len); } @@ -575,13 +573,5 @@ void destroy_extras(afl_state_t *afl) { ck_free(afl->extras); - for (i = 0; i < afl->a_extras_cnt; ++i) { - - ck_free(afl->a_extras[i].data); - - } - - ck_free(afl->a_extras); - } -- cgit v1.2.3 From ce92adcb9bcaba4894b58a26b2a10b11ef249c0a Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 14 Aug 2020 08:33:36 +0200 Subject: formatting --- src/afl-forkserver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 33dfde97..25983f26 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -875,7 +875,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, " - the target was compiled with afl-clang-lto and a constructor " "was\n" " instrumented, recompiling without AFL_LLVM_MAP_ADDR might solve " - "your problem\n\n" + "your \n" + " problem\n\n" " - Less likely, there is a horrible bug in the fuzzer. If other " "options\n" -- cgit v1.2.3 From ce513c4f3e97d293e57e0ef90ec9e501871c5644 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 14 Aug 2020 10:10:23 +0200 Subject: fix llvm12 -fuseld warning --- src/afl-fuzz-extras.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 94f50394..17f02984 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -28,7 +28,8 @@ /* helper function for auto_extras qsort */ static int compare_auto_extras_len(const void *ae1, const void *ae2) { - return ((struct auto_extra_data *)ae1)->len - ((struct auto_extra_data *)ae2)->len; + return ((struct auto_extra_data *)ae1)->len - + ((struct auto_extra_data *)ae2)->len; } @@ -36,7 +37,8 @@ static int compare_auto_extras_len(const void *ae1, const void *ae2) { static int compare_auto_extras_use_d(const void *ae1, const void *ae2) { - return ((struct auto_extra_data *)ae2)->hit_cnt - ((struct auto_extra_data *)ae1)->hit_cnt; + return ((struct auto_extra_data *)ae2)->hit_cnt - + ((struct auto_extra_data *)ae1)->hit_cnt; } -- cgit v1.2.3 From af14acf2c148b1aef10414d1dd6c929c49abc11e Mon Sep 17 00:00:00 2001 From: root Date: Fri, 14 Aug 2020 14:35:05 +0200 Subject: Revert "Merge branch 'debug' into dev" This reverts commit a7537b5511ad767d2240cf2dc6d3e261daa676f9, reversing changes made to 15e799f7ae666418e75c6a79db833c5316b21f97. --- src/afl-common.c | 155 +++++++++++++++++---------- src/afl-forkserver.c | 17 +-- src/afl-fuzz-bitmap.c | 62 +---------- src/afl-fuzz-init.c | 42 +------- src/afl-fuzz-one.c | 284 ++++++-------------------------------------------- src/afl-fuzz-queue.c | 177 +------------------------------ src/afl-fuzz-run.c | 99 ++++++------------ src/afl-fuzz-state.c | 30 ++---- src/afl-fuzz-stats.c | 5 +- src/afl-fuzz.c | 127 ++-------------------- 10 files changed, 192 insertions(+), 806 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index cefed8dc..367dec72 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -138,73 +138,62 @@ void argv_cpy_free(char **argv) { } -u8 *find_afl_binary(u8 *fname, u8 *own_loc) { - - u8 *tmp, *rsl, *own_copy, *cp; - - tmp = getenv("AFL_PATH"); - - if (tmp) { - - cp = alloc_printf("%s/%s", tmp, fname); - - if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); } - - return cp; +/* Rewrite argv for QEMU. */ - } +char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { - if (own_loc) { + char **new_argv = ck_alloc(sizeof(char *) * (argc + 4)); + u8 * tmp, *cp = NULL, *rsl, *own_copy; - own_copy = ck_strdup(own_loc); - rsl = strrchr(own_copy, '/'); + memcpy(&new_argv[3], &argv[1], (int)(sizeof(char *)) * (argc - 1)); + new_argv[argc - 1] = NULL; - if (rsl) { + new_argv[2] = *target_path_p; + new_argv[1] = "--"; - *rsl = 0; + /* Now we need to actually find the QEMU binary to put in argv[0]. */ - cp = alloc_printf("%s/%s", own_copy, fname); - ck_free(own_copy); + tmp = getenv("AFL_PATH"); - if (!access(cp, X_OK)) { return cp; } + if (tmp) { - } else { + cp = alloc_printf("%s/afl-qemu-trace", tmp); - ck_free(own_copy); + if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); } - } + *target_path_p = new_argv[0] = cp; + return new_argv; } - cp = alloc_printf("%s/%s", BIN_PATH, fname); - if (!access(cp, X_OK)) { return cp; } + own_copy = ck_strdup(own_loc); + rsl = strrchr(own_copy, '/'); - ck_free(cp); + if (rsl) { - return NULL; + *rsl = 0; -} + cp = alloc_printf("%s/afl-qemu-trace", own_copy); + ck_free(own_copy); -/* Rewrite argv for QEMU. */ + if (!access(cp, X_OK)) { -char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { + *target_path_p = new_argv[0] = cp; + return new_argv; - char **new_argv = ck_alloc(sizeof(char *) * (argc + 4)); - u8 * cp = NULL; + } - memcpy(&new_argv[3], &argv[1], (int)(sizeof(char *)) * (argc - 1)); - new_argv[argc - 1] = NULL; + } else { - new_argv[2] = *target_path_p; - new_argv[1] = "--"; + ck_free(own_copy); - /* Now we need to actually find the QEMU binary to put in argv[0]. */ + } - cp = find_afl_binary("afl-qemu-trace", own_loc); + if (!access(BIN_PATH "/afl-qemu-trace", X_OK)) { - if (cp) { + if (cp) { ck_free(cp); } + *target_path_p = new_argv[0] = ck_strdup(BIN_PATH "/afl-qemu-trace"); - *target_path_p = new_argv[0] = cp; return new_argv; } @@ -236,7 +225,7 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { char **new_argv = ck_alloc(sizeof(char *) * (argc + 3)); - u8 * cp = NULL; + u8 * tmp, *cp = NULL, *rsl, *own_copy; memcpy(&new_argv[2], &argv[1], (int)(sizeof(char *)) * (argc - 1)); new_argv[argc - 1] = NULL; @@ -245,16 +234,66 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { /* Now we need to actually find the QEMU binary to put in argv[0]. */ - cp = find_afl_binary("afl-qemu-trace", own_loc); + tmp = getenv("AFL_PATH"); + + if (tmp) { + + cp = alloc_printf("%s/afl-qemu-trace", tmp); - if (cp) { + if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); } ck_free(cp); - cp = find_afl_binary("afl-wine-trace", own_loc); - if (cp) { + cp = alloc_printf("%s/afl-wine-trace", tmp); - *target_path_p = new_argv[0] = cp; + if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); } + + *target_path_p = new_argv[0] = cp; + return new_argv; + + } + + own_copy = ck_strdup(own_loc); + rsl = strrchr(own_copy, '/'); + + if (rsl) { + + *rsl = 0; + + cp = alloc_printf("%s/afl-qemu-trace", own_copy); + + if (cp && !access(cp, X_OK)) { + + ck_free(cp); + + cp = alloc_printf("%s/afl-wine-trace", own_copy); + + if (!access(cp, X_OK)) { + + *target_path_p = new_argv[0] = cp; + return new_argv; + + } + + } + + ck_free(own_copy); + + } else { + + ck_free(own_copy); + + } + + u8 *ncp = BIN_PATH "/afl-qemu-trace"; + + if (!access(ncp, X_OK)) { + + ncp = BIN_PATH "/afl-wine-trace"; + + if (!access(ncp, X_OK)) { + + *target_path_p = new_argv[0] = ck_strdup(ncp); return new_argv; } @@ -262,21 +301,25 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { } SAYF("\n" cLRD "[-] " cRST - "Oops, unable to find the afl-qemu-trace and afl-wine-trace binaries.\n" - "The afl-qemu-trace binary must be built separately by following the " - "instructions\n" - "in qemu_mode/README.md. If you already have the binary installed, you " - "may need\n" - "to specify the location via AFL_PATH in the environment.\n\n" + "Oops, unable to find the '%s' binary. The binary must be " + "built\n" + " separately by following the instructions in " + "qemu_mode/README.md. " + "If you\n" + " already have the binary installed, you may need to specify " + "AFL_PATH in the\n" + " environment.\n\n" + " Of course, even without QEMU, afl-fuzz can still work with " "binaries that are\n" " instrumented at compile time with afl-gcc. It is also possible to " "use it as a\n" " traditional non-instrumented fuzzer by specifying '-n' in the " "command " - "line.\n"); + "line.\n", + ncp); - FATAL("Failed to locate 'afl-qemu-trace' and 'afl-wine-trace'."); + FATAL("Failed to locate '%s'.", ncp); } diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 173cc70f..25983f26 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -498,21 +498,11 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, char pid_buf[16]; sprintf(pid_buf, "%d", fsrv->fsrv_pid); - - if (fsrv->taint_mode) { - - setenv("__AFL_TARGET_PID3", pid_buf, 1); - - } else if (fsrv->cmplog_binary) { - + if (fsrv->cmplog_binary) setenv("__AFL_TARGET_PID2", pid_buf, 1); - - } else { - + else setenv("__AFL_TARGET_PID1", pid_buf, 1); - } - /* Close the unneeded endpoints. */ close(ctl_pipe[0]); @@ -947,7 +937,7 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { } else { - s32 fd; + s32 fd = fsrv->out_fd; if (fsrv->out_file) { @@ -966,7 +956,6 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { } else { - fd = fsrv->out_fd; lseek(fd, 0, SEEK_SET); } diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index db57061d..1b9df624 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -177,40 +177,6 @@ u32 count_bits(afl_state_t *afl, u8 *mem) { } -u32 count_bits_len(afl_state_t *afl, u8 *mem, u32 len) { - - u32 *ptr = (u32 *)mem; - u32 i = (len >> 2); - u32 ret = 0; - - (void)(afl); - - if (len % 4) i++; - - while (i--) { - - u32 v = *(ptr++); - - /* This gets called on the inverse, virgin bitmap; optimize for sparse - data. */ - - if (v == 0xffffffff) { - - ret += 32; - continue; - - } - - v -= ((v >> 1) & 0x55555555); - v = (v & 0x33333333) + ((v >> 2) & 0x33333333); - ret += (((v + (v >> 4)) & 0xF0F0F0F) * 0x01010101) >> 24; - - } - - return ret; - -} - /* Count the number of bytes set in the bitmap. Called fairly sporadically, mostly to update the status screen or calibrate and examine confirmed new paths. */ @@ -237,32 +203,6 @@ u32 count_bytes(afl_state_t *afl, u8 *mem) { } -u32 count_bytes_len(afl_state_t *afl, u8 *mem, u32 len) { - - u32 *ptr = (u32 *)mem; - u32 i = (len >> 2); - u32 ret = 0; - - (void)(afl); - - if (len % 4) i++; - - while (i--) { - - u32 v = *(ptr++); - - if (!v) { continue; } - if (v & 0x000000ff) { ++ret; } - if (v & 0x0000ff00) { ++ret; } - if (v & 0x00ff0000) { ++ret; } - if (v & 0xff000000) { ++ret; } - - } - - return ret; - -} - /* Count the number of non-255 bytes set in the bitmap. Used strictly for the status screen, several calls per second or so. */ @@ -655,7 +595,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #endif /* ^!SIMPLE_FILES */ - add_to_queue(afl, queue_fn, mem, len, afl->queue_top, 0); + add_to_queue(afl, queue_fn, len, 0); if (hnb == 2) { diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 359eef85..350a8599 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -712,7 +712,7 @@ void read_testcases(afl_state_t *afl) { if (!access(dfn, F_OK)) { passed_det = 1; } - add_to_queue(afl, fn2, NULL, st.st_size, NULL, passed_det); + add_to_queue(afl, fn2, st.st_size, passed_det); } @@ -771,13 +771,9 @@ void perform_dry_run(afl_state_t *afl) { close(fd); res = calibrate_case(afl, q, use_mem, 0, 1); + ck_free(use_mem); - if (afl->stop_soon) { - - ck_free(use_mem); - return; - - } + if (afl->stop_soon) { return; } if (res == afl->crash_mode || res == FSRV_RUN_NOBITS) { @@ -964,10 +960,6 @@ void perform_dry_run(afl_state_t *afl) { } - /* perform taint gathering on the input seed */ - if (afl->taint_mode) perform_taint_run(afl, q, q->fname, use_mem, q->len); - ck_free(use_mem); - q = q->next; } @@ -1446,10 +1438,6 @@ static void handle_existing_out_dir(afl_state_t *afl) { u8 *orig_q = alloc_printf("%s/queue", afl->out_dir); - u8 *fnt = alloc_printf("%s/taint", afl->out_dir); - mkdir(fnt, 0755); // ignore errors - ck_free(fnt); - afl->in_dir = alloc_printf("%s/_resume", afl->out_dir); rename(orig_q, afl->in_dir); /* Ignore errors */ @@ -1506,20 +1494,6 @@ static void handle_existing_out_dir(afl_state_t *afl) { if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); - if (afl->taint_mode) { - - fn = alloc_printf("%s/taint", afl->out_dir); - mkdir(fn, 0755); // ignore errors - - u8 *fn2 = alloc_printf("%s/taint/.input", afl->out_dir); - unlink(fn2); // ignore errors - ck_free(fn2); - - if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } - ck_free(fn); - - } - /* All right, let's do out_dir>/crashes/id:* and * out_dir>/hangs/id:*. */ @@ -1747,16 +1721,6 @@ void setup_dirs_fds(afl_state_t *afl) { if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); } ck_free(tmp); - /* Taint directory if taint_mode. */ - - if (afl->taint_mode) { - - tmp = alloc_printf("%s/taint", afl->out_dir); - if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); } - ck_free(tmp); - - } - /* Top-level directory for queue metadata used for session resume and related tasks. */ diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 6d52b2b4..57b53c9f 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -458,171 +458,28 @@ u8 fuzz_one_original(afl_state_t *afl) { } - u32 tmp_val = 0; - - if (unlikely(afl->taint_mode)) { - - tmp_val = afl->queue_cycle % 2; // starts with 1 - ret_val = 0; - - if (unlikely(afl->queue_cur->cal_failed && !tmp_val)) goto abandon_entry; - if (unlikely(!afl->skip_deterministic && !afl->queue_cur->passed_det && - !tmp_val)) - goto abandon_entry; - if ((!afl->queue_cur->taint_bytes_new || - afl->queue_cur->taint_bytes_new == afl->queue_cur->len) && - !tmp_val) - goto abandon_entry; - - ret_val = 1; - - s32 dst = 0, i; - temp_len = len = afl->queue_cur->len; - s32 j = 0; // tmp - - fd = open(afl->queue_cur->fname, O_RDONLY); - afl->taint_src = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (fd < 0 || (ssize_t)afl->taint_src == -1) - FATAL("unable to open '%s'", afl->queue_cur->fname); - close(fd); - afl->taint_needs_splode = 1; - - switch (tmp_val) { - - case 1: // fuzz only tainted bytes - - // special case: all or nothing tainted. in this case we act like - // nothing is special. this is not the taint you are looking for ... - if (!afl->queue_cur->taint_bytes_all || - afl->queue_cur->taint_bytes_all == (u32)len) { - - orig_in = in_buf = afl->taint_src; - afl->taint_needs_splode = 0; - break; - - } - - fd = open(afl->taint_input_file, O_RDONLY); - temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_all; - orig_in = in_buf = - mmap(0, len >= MAX_FILE - 65536 ? MAX_FILE : len + 65536, - PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (fd < 0 || (ssize_t)in_buf == -1) - FATAL("unable to open '%s'", afl->taint_input_file); - close(fd); - - fd = open(afl->queue_cur->fname_taint, O_RDONLY); - afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE, - MAP_PRIVATE, fd, 0); - if (fd < 0 || (ssize_t)in_buf == -1) - FATAL("unable to open '%s'", afl->queue_cur->fname_taint); - close(fd); - - for (i = 0; i < (s32)afl->queue_cur->len && dst < len; i++) - if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i]; - - // FIXME DEBUG TODO XXX - for (i = 0; i < (s32)afl->queue_cur->len; i++) { - - switch (afl->taint_map[i]) { - - case 0x0: - break; - case '!': - j++; - break; - default: - FATAL( - "invalid taint map entry byte 0x%02x at position %d " - "(passed_det:%d)\n", - afl->taint_map[i], i, afl->queue_cur->passed_det); - - } - - } - - if (j != len) - FATAL("different taint values in map vs in queue (%d != %d)", j, len); - - break; - - case 0: // fuzz only newly tainted bytes - - fd = open(afl->taint_input_file, O_RDONLY); - temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_new; - orig_in = in_buf = - mmap(0, len >= MAX_FILE - 65536 ? MAX_FILE : len + 65536, - PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (fd < 0 || (ssize_t)in_buf == -1) - FATAL("unable to open '%s'", afl->taint_input_file); - close(fd); - - u8 *fn = alloc_printf("%s.new", afl->queue_cur->fname_taint); - if (!fn) FATAL("OOM"); - fd = open(fn, O_RDWR); - afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE, - MAP_PRIVATE, fd, 0); - if (fd < 0 || (ssize_t)in_buf == -1) - FATAL("unable to open '%s' for %u bytes", fn, len); - close(fd); - ck_free(fn); - - for (i = 0; i < (s32)afl->queue_cur->len && dst < len; i++) - if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i]; - - // FIXME DEBUG TODO XXX - for (i = 0; i < (s32)afl->queue_cur->len; i++) { - - switch (afl->taint_map[i]) { - - case 0x0: - break; - case '!': - j++; - break; - default: - FATAL( - "invalid taint map entry byte 0x%02x at position %d " - "(passed_det:%d)\n", - afl->taint_map[i], i, afl->queue_cur->passed_det); - - } - - } - - if (j != len) - FATAL("different taint values in map vs in queue (%d != %d)", j, len); - - break; - - } - - } else { - - /* Map the test case into memory. */ - - fd = open(afl->queue_cur->fname, O_RDONLY); + /* Map the test case into memory. */ - if (unlikely(fd < 0)) { + fd = open(afl->queue_cur->fname, O_RDONLY); - PFATAL("Unable to open '%s'", afl->queue_cur->fname); + if (unlikely(fd < 0)) { - } + PFATAL("Unable to open '%s'", afl->queue_cur->fname); - len = afl->queue_cur->len; + } - orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + len = afl->queue_cur->len; - if (unlikely(orig_in == MAP_FAILED)) { + orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - PFATAL("Unable to mmap '%s' with len %d", afl->queue_cur->fname, len); + if (unlikely(orig_in == MAP_FAILED)) { - } - - close(fd); + PFATAL("Unable to mmap '%s' with len %d", afl->queue_cur->fname, len); } + close(fd); + /* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every single byte anyway, so it wouldn't give us any performance or memory usage benefits. */ @@ -645,12 +502,8 @@ u8 fuzz_one_original(afl_state_t *afl) { afl->queue_cur->exec_cksum = 0; - if (unlikely(afl->taint_needs_splode)) - res = calibrate_case(afl, afl->queue_cur, afl->taint_src, - afl->queue_cycle - 1, 0); - else - res = calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, - 0); + res = + calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0); if (unlikely(res == FSRV_RUN_ERROR)) { @@ -673,8 +526,8 @@ u8 fuzz_one_original(afl_state_t *afl) { * TRIMMING * ************/ - if (unlikely(!afl->non_instrumented_mode && !afl->queue_cur->trim_done && - !afl->disable_trim && !afl->taint_needs_splode)) { + if (!afl->non_instrumented_mode && !afl->queue_cur->trim_done && + !afl->disable_trim) { u8 res = trim_case(afl, afl->queue_cur, in_buf); @@ -711,26 +564,13 @@ u8 fuzz_one_original(afl_state_t *afl) { if (afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized) { - int res; - if (unlikely(afl->taint_needs_splode)) { - - len = afl->queue_cur->len; - memcpy(out_buf, afl->taint_src, len); - res = input_to_state_stage(afl, afl->taint_src, out_buf, len, - afl->queue_cur->exec_cksum); - // just abandon as success - ret_val = 0; - res = 1; - - } else { + if (input_to_state_stage(afl, in_buf, out_buf, len, + afl->queue_cur->exec_cksum)) { - res = input_to_state_stage(afl, in_buf, out_buf, len, - afl->queue_cur->exec_cksum); + goto abandon_entry; } - if (unlikely(res)) { goto abandon_entry; } - } /* Skip right away if -d is given, if it has not been chosen sufficiently @@ -2293,18 +2133,8 @@ havoc_stage: if (actually_clone) { - if (unlikely(afl->taint_needs_splode)) { - - clone_len = choose_block_len(afl, afl->queue_cur->len); - clone_from = - rand_below(afl, afl->queue_cur->len - clone_len + 1); - - } else { - - clone_len = choose_block_len(afl, temp_len); - clone_from = rand_below(afl, temp_len - clone_len + 1); - - } + clone_len = choose_block_len(afl, temp_len); + clone_from = rand_below(afl, temp_len - clone_len + 1); } else { @@ -2326,11 +2156,7 @@ havoc_stage: if (actually_clone) { - if (unlikely(afl->taint_needs_splode)) - memcpy(new_buf + clone_to, afl->taint_src + clone_from, - clone_len); - else - memcpy(new_buf + clone_to, out_buf + clone_from, clone_len); + memcpy(new_buf + clone_to, out_buf + clone_from, clone_len); } else { @@ -2342,7 +2168,7 @@ havoc_stage: } /* Tail */ - memmove(new_buf + clone_to + clone_len, out_buf + clone_to, + memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, temp_len - clone_to); swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); @@ -2363,49 +2189,16 @@ havoc_stage: if (temp_len < 2) { break; } - if (unlikely(afl->taint_needs_splode)) { - - copy_len = choose_block_len(afl, afl->queue_cur->len - 1); - copy_from = rand_below(afl, afl->queue_cur->len - copy_len + 1); - copy_to = rand_below(afl, temp_len + 1); - - } else { + copy_len = choose_block_len(afl, temp_len - 1); - copy_len = choose_block_len(afl, temp_len - 1); - copy_from = rand_below(afl, temp_len - copy_len + 1); - copy_to = rand_below(afl, temp_len - copy_len + 1); - - } + copy_from = rand_below(afl, temp_len - copy_len + 1); + copy_to = rand_below(afl, temp_len - copy_len + 1); if (rand_below(afl, 4)) { if (copy_from != copy_to) { - if (unlikely(afl->taint_needs_splode)) { - - if (temp_len >= (s32)(copy_to + copy_len)) { - - memcpy(out_buf + copy_to, afl->taint_src + copy_from, - copy_len); - - } else { - - u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), - copy_to + copy_len); - memcpy(new_buf, in_buf, copy_to); - memcpy(new_buf + copy_to, afl->taint_src + copy_from, - copy_len); - swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); - out_buf = new_buf; - temp_len = copy_to + copy_len; - - } - - } else { - - memmove(out_buf + copy_to, out_buf + copy_from, copy_len); - - } + memmove(out_buf + copy_to, out_buf + copy_from, copy_len); } @@ -2671,17 +2464,10 @@ havoc_stage: splices them together at some offset, then relies on the havoc code to mutate that blob. */ - u32 saved_len; - - if (unlikely(afl->taint_needs_splode)) - saved_len = afl->taint_len; - else - saved_len = afl->queue_cur->len; - retry_splicing: if (afl->use_splicing && splice_cycle++ < SPLICE_CYCLES && - afl->queued_paths > 1 && saved_len > 1) { + afl->queued_paths > 1 && afl->queue_cur->len > 1) { struct queue_entry *target; u32 tid, split_at; @@ -2694,7 +2480,7 @@ retry_splicing: if (in_buf != orig_in) { in_buf = orig_in; - len = saved_len; + len = afl->queue_cur->len; } @@ -2765,8 +2551,6 @@ retry_splicing: ret_val = 0; - goto abandon_entry; - /* we are through with this queue entry - for this iteration */ abandon_entry: @@ -2786,17 +2570,7 @@ abandon_entry: ++afl->queue_cur->fuzz_level; - if (unlikely(afl->taint_needs_splode)) { - - munmap(afl->taint_src, afl->queue_cur->len); - munmap(orig_in, afl->taint_len); - munmap(afl->taint_map, afl->queue_cur->len); - - } else { - - munmap(orig_in, afl->queue_cur->len); - - } + munmap(orig_in, afl->queue_cur->len); return ret_val; diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 43794018..f35df914 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -103,169 +103,6 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) { } -void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname, - u8 *mem, u32 len) { - - u8 * ptr, *fn = fname; - u32 bytes = 0, plen = len; - struct queue_entry *prev = q->prev; - - if (plen % 4) plen = plen + 4 - (len % 4); - - if ((ptr = strrchr(fname, '/')) != NULL) fn = ptr + 1; - q->fname_taint = alloc_printf("%s/taint/%s", afl->out_dir, fn); - - if (q->fname_taint) { - - u8 *save = ck_maybe_grow(BUF_PARAMS(out_scratch), afl->fsrv.map_size); - memcpy(save, afl->taint_fsrv.trace_bits, afl->fsrv.map_size); - - afl->taint_fsrv.map_size = plen; // speed :) - write_to_testcase(afl, mem, len); - if (afl_fsrv_run_target(&afl->taint_fsrv, afl->fsrv.exec_tmout * 4, - &afl->stop_soon) == 0) { - - bytes = q->taint_bytes_all = - count_bytes_len(afl, afl->taint_fsrv.trace_bits, plen); - if (afl->debug) - fprintf(stderr, "Debug: tainted %u out of %u bytes\n", bytes, len); - - /* DEBUG FIXME TODO XXX */ - u32 i; - for (i = 0; i < len; i++) { - - if (afl->taint_fsrv.trace_bits[i] && - afl->taint_fsrv.trace_bits[i] != '!') - FATAL("invalid taint map value %02x at pos %d", - afl->taint_fsrv.trace_bits[i], i); - - } - - if (len < plen) - for (i = len; i < plen; i++) { - - if (afl->taint_fsrv.trace_bits[i]) - FATAL("invalid taint map value %02x in padding at pos %d", - afl->taint_fsrv.trace_bits[i], i); - - } - - } - - // if all is tainted we do not need to write taint data away - if (bytes && bytes < len) { - - // save the bytes away - int w = open(q->fname_taint, O_CREAT | O_WRONLY, 0644); - if (w >= 0) { - - ck_write(w, afl->taint_fsrv.trace_bits, len, q->fname_taint); - close(w); - - // find the highest tainted offset in the input (for trim opt) - s32 i = len; - while (i > 0 && !afl->taint_fsrv.trace_bits[i - 1]) - i--; - q->taint_bytes_highest = i; - - afl->taint_count++; - - } else { - - FATAL("could not create %s", q->fname_taint); - q->taint_bytes_all = bytes = 0; - - } - - // it is possible that there is no main taint file - if the whole file - // is tainted - but a .new taint file if it had new tainted bytes - - // check if there is a previous queue entry and if it had taint - if (bytes && prev && prev->taint_bytes_all && - prev->taint_bytes_all < prev->len) { - - // check if there are new bytes in the taint vs the previous - int r = open(prev->fname_taint, O_RDONLY); - - if (r >= 0) { - - u8 *bufr = mmap(0, prev->len, PROT_READ, MAP_PRIVATE, r, 0); - - if ((ssize_t)bufr != -1) { - - u32 i; - u8 *tmp = ck_maybe_grow(BUF_PARAMS(in_scratch), plen); - memset(tmp, 0, plen); - - for (i = 0; i < len; i++) - if (afl->taint_fsrv.trace_bits[i] && (i >= prev->len || !bufr[i])) - tmp[i] = '!'; - - q->taint_bytes_new = count_bytes_len(afl, tmp, plen); - - if (afl->debug) - fprintf(stderr, "Debug: %u new taint out of %u bytes\n", bytes, - len); - - if (q->taint_bytes_new) { - - u8 *fnw = alloc_printf("%s.new", q->fname_taint); - if (fnw) { - - int w = open(fnw, O_CREAT | O_WRONLY, 0644); - if (w >= 0) { - - ck_write(w, tmp, plen, fnw); - close(w); - - } else { - - FATAL("count not create '%s'", fnw); - q->taint_bytes_new = 0; - - } - - ck_free(fnw); - - } else { - - q->taint_bytes_new = 0; - - } - - } - - munmap(bufr, prev->len); - - } - - close(r); - - } - - } - - } - - memcpy(afl->taint_fsrv.trace_bits, save, afl->fsrv.map_size); - - } - - if (!bytes) { - - q->taint_bytes_highest = q->taint_bytes_all = q->taint_bytes_new = 0; - - if (q->fname_taint) { - - ck_free(q->fname_taint); - q->fname_taint = NULL; - - } - - } - -} - /* check if ascii or UTF-8 */ static u8 check_if_text(struct queue_entry *q) { @@ -375,12 +212,10 @@ static u8 check_if_text(struct queue_entry *q) { /* Append new test case to the queue. */ -void add_to_queue(afl_state_t *afl, u8 *fname, u8 *mem, u32 len, - struct queue_entry *prev_q, u8 passed_det) { +void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { struct queue_entry *q = ck_alloc(sizeof(struct queue_entry)); - q->prev = prev_q; q->fname = fname; q->len = len; q->depth = afl->cur_depth + 1; @@ -419,13 +254,6 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u8 *mem, u32 len, afl->last_path_time = get_cur_time(); - /* trigger the tain gathering if this is not a dry run */ - if (afl->taint_mode && mem) { perform_taint_run(afl, q, fname, mem, len); } - - /* only redqueen currently uses is_ascii */ - if (afl->shm.cmplog_mode) q->is_ascii = check_if_text(q); - - /* run custom mutators afl_custom_queue_new_entry() */ if (afl->custom_mutators_count) { LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { @@ -445,6 +273,9 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u8 *mem, u32 len, } + /* only redqueen currently uses is_ascii */ + if (afl->shm.cmplog_mode) q->is_ascii = check_if_text(q); + } /* Destroy the entire queue. */ diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 5381723d..d3f823c9 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -350,9 +350,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, } - if (unlikely(afl->taint_mode)) - q->exec_cksum = 0; - else if (q->exec_cksum) { + if (q->exec_cksum) { memcpy(afl->first_trace, afl->fsrv.trace_bits, afl->fsrv.map_size); hnb = has_new_bits(afl, afl->virgin_bits); @@ -755,65 +753,56 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { while (remove_pos < q->len) { u32 trim_avail = MIN(remove_len, q->len - remove_pos); + u64 cksum; - if (likely((!q->taint_bytes_highest) || - (q->len - trim_avail > q->taint_bytes_highest))) { + write_with_gap(afl, in_buf, q->len, remove_pos, trim_avail); - u64 cksum; + fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); + ++afl->trim_execs; - write_with_gap(afl, in_buf, q->len, remove_pos, trim_avail); + if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; } - fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); - ++afl->trim_execs; - - if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; } - - /* Note that we don't keep track of crashes or hangs here; maybe TODO? - */ - - cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); - - /* If the deletion had no impact on the trace, make it permanent. This - isn't perfect for variable-path inputs, but we're just making a - best-effort pass, so it's not a big deal if we end up with false - negatives every now and then. */ - - if (cksum == q->exec_cksum) { + /* Note that we don't keep track of crashes or hangs here; maybe TODO? + */ - u32 move_tail = q->len - remove_pos - trim_avail; + cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); - q->len -= trim_avail; - len_p2 = next_pow2(q->len); + /* If the deletion had no impact on the trace, make it permanent. This + isn't perfect for variable-path inputs, but we're just making a + best-effort pass, so it's not a big deal if we end up with false + negatives every now and then. */ - memmove(in_buf + remove_pos, in_buf + remove_pos + trim_avail, - move_tail); + if (cksum == q->exec_cksum) { - /* Let's save a clean trace, which will be needed by - update_bitmap_score once we're done with the trimming stuff. */ + u32 move_tail = q->len - remove_pos - trim_avail; - if (!needs_write) { + q->len -= trim_avail; + len_p2 = next_pow2(q->len); - needs_write = 1; - memcpy(afl->clean_trace, afl->fsrv.trace_bits, afl->fsrv.map_size); + memmove(in_buf + remove_pos, in_buf + remove_pos + trim_avail, + move_tail); - } + /* Let's save a clean trace, which will be needed by + update_bitmap_score once we're done with the trimming stuff. */ - } else { + if (!needs_write) { - remove_pos += remove_len; + needs_write = 1; + memcpy(afl->clean_trace, afl->fsrv.trace_bits, afl->fsrv.map_size); } - /* Since this can be slow, update the screen every now and then. */ - if (!(trim_exec++ % afl->stats_update_freq)) { show_stats(afl); } - ++afl->stage_cur; - } else { remove_pos += remove_len; } + /* Since this can be slow, update the screen every now and then. */ + + if (!(trim_exec++ % afl->stats_update_freq)) { show_stats(afl); } + ++afl->stage_cur; + } remove_len >>= 1; @@ -866,8 +855,6 @@ abort_trimming: } -#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size - /* Write a modified test case, run program, process results. Handle error conditions, returning 1 if it's time to bail out. This is a helper function for fuzz_one(). */ @@ -877,32 +864,6 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { u8 fault; - if (unlikely(afl->taint_needs_splode)) { - - s32 new_len = afl->queue_cur->len + len - afl->taint_len; - if (new_len < 4) - new_len = 4; - else if (new_len > MAX_FILE) - new_len = MAX_FILE; - u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), new_len); - - u32 i, taint = 0; - for (i = 0; i < (u32)new_len; i++) { - - if (i >= afl->taint_len || i >= afl->queue_cur->len || afl->taint_map[i]) - new_buf[i] = out_buf[taint++]; - else - new_buf[i] = afl->taint_src[i]; - - } - - swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); - - out_buf = new_buf; - len = new_len; - - } - write_to_testcase(afl, out_buf, len); fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); @@ -950,5 +911,3 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { } -#undef BUF_PARAMS - diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index a8416eb1..d4de91a4 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -75,7 +75,7 @@ static list_t afl_states = {.element_prealloc_count = 0}; /* Initializes an afl_state_t. */ -void afl_state_init_1(afl_state_t *afl, uint32_t map_size) { +void afl_state_init(afl_state_t *afl, uint32_t map_size) { /* thanks to this memset, growing vars like out_buf and out_size are NULL/0 by default. */ @@ -100,6 +100,16 @@ void afl_state_init_1(afl_state_t *afl, uint32_t map_size) { afl->cpu_aff = -1; /* Selected CPU core */ #endif /* HAVE_AFFINITY */ + afl->virgin_bits = ck_alloc(map_size); + afl->virgin_tmout = ck_alloc(map_size); + afl->virgin_crash = ck_alloc(map_size); + afl->var_bytes = ck_alloc(map_size); + afl->top_rated = ck_alloc(map_size * sizeof(void *)); + afl->clean_trace = ck_alloc(map_size); + afl->clean_trace_custom = ck_alloc(map_size); + afl->first_trace = ck_alloc(map_size); + afl->map_tmp_buf = ck_alloc(map_size); + afl->fsrv.use_stdin = 1; afl->fsrv.map_size = map_size; // afl_state_t is not available in forkserver.c @@ -151,24 +161,6 @@ void afl_state_init_1(afl_state_t *afl, uint32_t map_size) { } -void afl_state_init_2(afl_state_t *afl, uint32_t map_size) { - - afl->shm.map_size = map_size ? map_size : MAP_SIZE; - - afl->virgin_bits = ck_alloc(map_size); - afl->virgin_tmout = ck_alloc(map_size); - afl->virgin_crash = ck_alloc(map_size); - afl->var_bytes = ck_alloc(map_size); - afl->top_rated = ck_alloc(map_size * sizeof(void *)); - afl->clean_trace = ck_alloc(map_size); - afl->clean_trace_custom = ck_alloc(map_size); - afl->first_trace = ck_alloc(map_size); - afl->map_tmp_buf = ck_alloc(map_size); - - afl->fsrv.map_size = map_size; - -} - /*This sets up the environment variables for afl-fuzz into the afl_state * struct*/ diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 0cc06e12..aeb290bd 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -116,7 +116,6 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, "edges_found : %u\n" "var_byte_count : %u\n" "havoc_expansion : %u\n" - "tainted_inputs : %u\n" "afl_banner : %s\n" "afl_version : " VERSION "\n" @@ -150,8 +149,8 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, #else -1, #endif - t_bytes, afl->var_byte_count, afl->expand_havoc, afl->taint_count, - afl->use_banner, afl->unicorn_mode ? "unicorn" : "", + t_bytes, afl->var_byte_count, afl->expand_havoc, afl->use_banner, + afl->unicorn_mode ? "unicorn" : "", afl->fsrv.qemu_mode ? "qemu " : "", afl->non_instrumented_mode ? " non_instrumented " : "", afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "", diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 106aa550..5dd092f2 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -53,9 +53,6 @@ static void at_exit() { ptr = getenv("__AFL_TARGET_PID2"); if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL); - ptr = getenv("__AFL_TARGET_PID3"); - if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL); - i = 0; while (list[i] != NULL) { @@ -92,8 +89,6 @@ static void usage(u8 *argv0, int more_help) { " -o dir - output directory for fuzzer findings\n\n" "Execution control settings:\n" - " -A - use first level taint analysis (see " - "qemu_taint/README.md)\n" " -p schedule - power schedules compute a seed's performance score. " "debug = 1; } map_size = get_map_size(); - afl_state_init_1(afl, map_size); + afl_state_init(afl, map_size); afl->debug = debug; afl_fsrv_init(&afl->fsrv); @@ -283,15 +277,10 @@ int main(int argc, char **argv_orig, char **envp) { while ((opt = getopt( argc, argv, - "+b:c:i:I:o:f:F:m:t:T:dDnCB:S:M:x:QANUWe:p:s:V:E:L:hRP:")) > 0) { + "+b:c:i:I:o:f:F:m:t:T:dDnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:")) > 0) { switch (opt) { - case 'A': - afl->taint_mode = 1; - if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_QEMU; } - break; - case 'I': afl->infoexec = optarg; break; @@ -499,7 +488,7 @@ int main(int argc, char **argv_orig, char **envp) { if (!optarg) { FATAL("Wrong usage of -m"); } - if (!strcmp(optarg, "none") || !strcmp(optarg, "0")) { + if (!strcmp(optarg, "none")) { afl->fsrv.mem_limit = 0; break; @@ -829,15 +818,6 @@ int main(int argc, char **argv_orig, char **envp) { } - if (afl->taint_mode && afl->fsrv.map_size < MAX_FILE) { - - real_map_size = map_size; - map_size = MAX_FILE; - - } - - afl_state_init_2(afl, map_size); - if (!mem_limit_given && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260; OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" " @@ -845,7 +825,8 @@ int main(int argc, char **argv_orig, char **envp) { OKF("afl++ is open source, get it at " "https://github.com/AFLplusplus/AFLplusplus"); OKF("Power schedules from github.com/mboehme/aflfast"); - OKF("Python Mutator from github.com/choller/afl"); + OKF("Python Mutator and llvm_mode instrument file list from " + "github.com/choller/afl"); OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL"); if (afl->sync_id && afl->is_main_node && @@ -891,19 +872,6 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->crash_mode) { FATAL("-C and -n are mutually exclusive"); } if (afl->fsrv.qemu_mode) { FATAL("-Q and -n are mutually exclusive"); } if (afl->unicorn_mode) { FATAL("-U and -n are mutually exclusive"); } - if (afl->taint_mode) { FATAL("-A and -n are mutually exclusive"); } - - } - - if (afl->limit_time_sig != 0 && afl->taint_mode) { - - FATAL("-A and -L are mutually exclusive"); - - } - - if (afl->unicorn_mode != 0 && afl->taint_mode) { - - FATAL("-A and -U are mutually exclusive"); } @@ -1004,7 +972,7 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->afl_env.afl_preload) { - if (afl->fsrv.qemu_mode || afl->taint_mode) { + if (afl->fsrv.qemu_mode) { u8 *qemu_preload = getenv("QEMU_SET_ENV"); u8 *afl_preload = getenv("AFL_PRELOAD"); @@ -1100,13 +1068,6 @@ int main(int argc, char **argv_orig, char **envp) { afl->fsrv.trace_bits = afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode); - if (real_map_size && map_size != real_map_size) { - - afl->fsrv.map_size = real_map_size; - if (afl->cmplog_binary) afl->cmplog_fsrv.map_size = real_map_size; - - } - if (!afl->in_bitmap) { memset(afl->virgin_bits, 255, afl->fsrv.map_size); } memset(afl->virgin_tmout, 255, afl->fsrv.map_size); memset(afl->virgin_crash, 255, afl->fsrv.map_size); @@ -1262,6 +1223,7 @@ int main(int argc, char **argv_orig, char **envp) { ACTF("Spawning cmplog forkserver"); afl_fsrv_init_dup(&afl->cmplog_fsrv, &afl->fsrv); + // TODO: this is semi-nice afl->cmplog_fsrv.trace_bits = afl->fsrv.trace_bits; afl->cmplog_fsrv.qemu_mode = afl->fsrv.qemu_mode; afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary; @@ -1272,70 +1234,6 @@ int main(int argc, char **argv_orig, char **envp) { } - if (afl->taint_mode) { - - ACTF("Spawning qemu_taint forkserver"); - - u8 *disable = getenv("AFL_DISABLE_LLVM_INSTRUMENTATION"); - setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); - - afl_fsrv_init_dup(&afl->taint_fsrv, &afl->fsrv); - afl->taint_fsrv.taint_mode = 1; - afl->taint_fsrv.trace_bits = afl->fsrv.trace_bits; - - ck_free(afl->taint_fsrv.target_path); - afl->argv_taint = ck_alloc(sizeof(char *) * (argc + 4 - optind)); - afl->taint_fsrv.target_path = find_afl_binary("afl-qemu-taint", argv[0]); - afl->argv_taint[0] = find_afl_binary("afl-qemu-taint", argv[0]); - if (!afl->argv_taint[0]) - FATAL( - "Cannot find 'afl-qemu-taint', read qemu_taint/README.md on how to " - "build it."); - u32 idx = optind - 1, offset = 0; - do { - - idx++; - offset++; - afl->argv_taint[offset] = argv[idx]; - - } while (argv[idx] != NULL); - - if (afl->fsrv.use_stdin) - unsetenv("AFL_TAINT_INPUT"); - else - setenv("AFL_TAINT_INPUT", afl->fsrv.out_file, 1); - afl_fsrv_start(&afl->taint_fsrv, afl->argv_taint, &afl->stop_soon, - afl->afl_env.afl_debug_child_output); - - afl->taint_input_file = alloc_printf("%s/taint/.input", afl->out_dir); - int fd = open(afl->taint_input_file, O_CREAT | O_TRUNC | O_RDWR, 0644); - if (fd < 0) - FATAL("Cannot create taint inpu file '%s'", afl->taint_input_file); - lseek(fd, MAX_FILE, SEEK_SET); - ck_write(fd, "\0", 1, afl->taint_input_file); - - if (!disable) unsetenv("AFL_DISABLE_LLVM_INSTRUMENTATION"); - - OKF("Taint forkserver successfully started"); - - const rlim_t kStackSize = 128L * 1024L * 1024L; // min stack size = 128 Mb - struct rlimit rl; - rl.rlim_cur = kStackSize; - if (getrlimit(RLIMIT_STACK, &rl) != 0) - WARNF("Setting a higher stack size failed!"); - - #define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size - u8 *tmp1 = ck_maybe_grow(BUF_PARAMS(eff), MAX_FILE + 4096); - u8 *tmp2 = ck_maybe_grow(BUF_PARAMS(ex), MAX_FILE + 4096); - u8 *tmp3 = ck_maybe_grow(BUF_PARAMS(in_scratch), MAX_FILE + 4096); - u8 *tmp4 = ck_maybe_grow(BUF_PARAMS(out), MAX_FILE + 4096); - u8 *tmp5 = ck_maybe_grow(BUF_PARAMS(out_scratch), MAX_FILE + 4096); - #undef BUF_PARAMS - if (!tmp1 || !tmp2 || !tmp3 || !tmp4 || !tmp5) - FATAL("memory issues. me hungry, feed me!"); - - } - perform_dry_run(afl); cull_queue(afl); @@ -1410,7 +1308,7 @@ int main(int argc, char **argv_orig, char **envp) { break; case 1: if (afl->limit_time_sig == 0 && !afl->custom_only && - !afl->python_only && !afl->taint_mode) { + !afl->python_only) { afl->limit_time_sig = -1; afl->limit_time_puppet = 0; @@ -1598,11 +1496,8 @@ stop_fuzzing: } - if (afl->cmplog_binary) afl_fsrv_deinit(&afl->cmplog_fsrv); - if (afl->taint_mode) afl_fsrv_deinit(&afl->taint_fsrv); afl_fsrv_deinit(&afl->fsrv); if (afl->orig_cmdline) { ck_free(afl->orig_cmdline); } - if (afl->argv_taint) { ck_free(afl->argv_taint); } ck_free(afl->fsrv.target_path); ck_free(afl->fsrv.out_file); ck_free(afl->sync_id); -- cgit v1.2.3 From 2f28ecd3a522faff6bcdf42b8cb0fd8cd3dc28ce Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 15 Aug 2020 20:51:57 +0200 Subject: more unlikely --- src/afl-fuzz-one.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 57b53c9f..5a4ac8ef 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -526,8 +526,8 @@ u8 fuzz_one_original(afl_state_t *afl) { * TRIMMING * ************/ - if (!afl->non_instrumented_mode && !afl->queue_cur->trim_done && - !afl->disable_trim) { + if (unlikely(!afl->non_instrumented_mode && !afl->queue_cur->trim_done && + !afl->disable_trim)) { u8 res = trim_case(afl, afl->queue_cur, in_buf); @@ -562,7 +562,7 @@ u8 fuzz_one_original(afl_state_t *afl) { if (unlikely(perf_score == 0)) { goto abandon_entry; } - if (afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized) { + if (unlikely(afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized)) { if (input_to_state_stage(afl, in_buf, out_buf, len, afl->queue_cur->exec_cksum)) { @@ -591,8 +591,9 @@ u8 fuzz_one_original(afl_state_t *afl) { /* Skip deterministic fuzzing if exec path checksum puts this out of scope for this main instance. */ - if (afl->main_node_max && (afl->queue_cur->exec_cksum % afl->main_node_max) != - afl->main_node_id - 1) { + if (unlikely(afl->main_node_max && + (afl->queue_cur->exec_cksum % afl->main_node_max) != + afl->main_node_id - 1)) { goto custom_mutator_stage; @@ -2753,7 +2754,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { orig_perf = perf_score = calculate_score(afl, afl->queue_cur); - if (afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized) { + if (unlikely(afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized)) { if (input_to_state_stage(afl, in_buf, out_buf, len, afl->queue_cur->exec_cksum)) { -- cgit v1.2.3 From 43214d6b46643f70fc7979dd37a23bda76ed3171 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 15 Aug 2020 22:10:28 +0200 Subject: more likely --- src/afl-fuzz-one.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 5a4ac8ef..0a4be320 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -95,7 +95,7 @@ static u32 choose_block_len(afl_state_t *afl, u32 limit) { default: - if (rand_below(afl, 10)) { + if (likely(rand_below(afl, 10))) { min_value = HAVOC_BLK_MEDIUM; max_value = HAVOC_BLK_LARGE; @@ -421,7 +421,7 @@ u8 fuzz_one_original(afl_state_t *afl) { if (((afl->queue_cur->was_fuzzed > 0 || afl->queue_cur->fuzz_level > 0) || !afl->queue_cur->favored) && - rand_below(afl, 100) < SKIP_TO_NEW_PROB) { + likely(rand_below(afl, 100) < SKIP_TO_NEW_PROB)) { return 1; @@ -438,11 +438,11 @@ u8 fuzz_one_original(afl_state_t *afl) { if (afl->queue_cycle > 1 && (afl->queue_cur->fuzz_level == 0 || afl->queue_cur->was_fuzzed)) { - if (rand_below(afl, 100) < SKIP_NFAV_NEW_PROB) { return 1; } + if (likely(rand_below(afl, 100) < SKIP_NFAV_NEW_PROB)) { return 1; } } else { - if (rand_below(afl, 100) < SKIP_NFAV_OLD_PROB) { return 1; } + if (likely(rand_below(afl, 100) < SKIP_NFAV_OLD_PROB)) { return 1; } } @@ -2132,7 +2132,7 @@ havoc_stage: u32 clone_from, clone_to, clone_len; u8 *new_buf; - if (actually_clone) { + if (likely(actually_clone)) { clone_len = choose_block_len(afl, temp_len); clone_from = rand_below(afl, temp_len - clone_len + 1); @@ -2155,7 +2155,7 @@ havoc_stage: /* Inserted part */ - if (actually_clone) { + if (likely(actually_clone)) { memcpy(new_buf + clone_to, out_buf + clone_from, clone_len); @@ -2195,7 +2195,7 @@ havoc_stage: copy_from = rand_below(afl, temp_len - copy_len + 1); copy_to = rand_below(afl, temp_len - copy_len + 1); - if (rand_below(afl, 4)) { + if (likely(rand_below(afl, 4))) { if (copy_from != copy_to) { -- cgit v1.2.3 From 7470b475a9b5e65afa78ca493867d8c980bd66db Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 18 Aug 2020 00:50:52 +0200 Subject: Reworked maybe_grow to take a single ptr, renamed to afl_realloc (#505) * maybe_grow takes a single ptr * fixed use_deflate * reworked maybe_grow_bufsize * helper to access underlying buf * remove redundant realloc_block * code format * fixes * added unit tests * renamed maybe_grow to afl_realloc * BUF_PARAMS -> AFL_BUF_PARAM --- src/afl-fuzz-extras.c | 12 +++++--- src/afl-fuzz-mutators.c | 3 +- src/afl-fuzz-one.c | 79 ++++++++++++++++++++++++++++--------------------- src/afl-fuzz-python.c | 20 ++++++++----- src/afl-fuzz-queue.c | 7 ++--- src/afl-fuzz-redqueen.c | 8 ++--- src/afl-fuzz-run.c | 7 ++--- src/afl-fuzz-state.c | 14 ++++----- 8 files changed, 83 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 17f02984..88262a98 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -152,8 +152,10 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len, /* Okay, let's allocate memory and copy data between "...", handling \xNN escaping, \\, and \". */ - afl->extras = ck_realloc_block( - afl->extras, (afl->extras_cnt + 1) * sizeof(struct extra_data)); + afl->extras = + afl_realloc((void **)&afl->extras, + (afl->extras_cnt + 1) * sizeof(struct extra_data)); + if (unlikely(!afl->extras)) { PFATAL("alloc"); } wptr = afl->extras[afl->extras_cnt].data = ck_alloc(rptr - lptr); @@ -296,8 +298,10 @@ void load_extras(afl_state_t *afl, u8 *dir) { if (min_len > st.st_size) { min_len = st.st_size; } if (max_len < st.st_size) { max_len = st.st_size; } - afl->extras = ck_realloc_block( - afl->extras, (afl->extras_cnt + 1) * sizeof(struct extra_data)); + afl->extras = + afl_realloc((void **)&afl->extras, + (afl->extras_cnt + 1) * sizeof(struct extra_data)); + if (unlikely(!afl->extras)) { PFATAL("alloc"); } afl->extras[afl->extras_cnt].data = ck_alloc(st.st_size); afl->extras[afl->extras_cnt].len = st.st_size; diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 0fa646f9..22578df9 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -122,9 +122,8 @@ void destroy_custom_mutators(afl_state_t *afl) { if (el->post_process_buf) { - ck_free(el->post_process_buf); + afl_free(el->post_process_buf); el->post_process_buf = NULL; - el->post_process_size = 0; } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 0a4be320..3bf0c195 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -364,8 +364,6 @@ static void locate_diffs(u8 *ptr1, u8 *ptr2, u32 len, s32 *first, s32 *last) { #endif /* !IGNORE_FINDS */ -#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size - /* Take the current entry from the queue, fuzz it for a while. This function is a tad too long... returns 0 if fuzzed successfully, 1 if skipped or bailed out. */ @@ -384,9 +382,6 @@ u8 fuzz_one_original(afl_state_t *afl) { u8 a_collect[MAX_AUTO_EXTRA]; u32 a_len = 0; -/* Not pretty, but saves a lot of writing */ -#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size - #ifdef IGNORE_FINDS /* In IGNORE_FINDS mode, skip any entries that weren't in the @@ -484,7 +479,8 @@ u8 fuzz_one_original(afl_state_t *afl) { single byte anyway, so it wouldn't give us any performance or memory usage benefits. */ - out_buf = ck_maybe_grow(BUF_PARAMS(out), len); + out_buf = afl_realloc(AFL_BUF_PARAM(out), len); + if (unlikely(!out_buf)) { PFATAL("alloc"); } afl->subseq_tmouts = 0; @@ -800,7 +796,8 @@ u8 fuzz_one_original(afl_state_t *afl) { /* Initialize effector map for the next step (see comments below). Always flag first and last byte as doing something. */ - eff_map = ck_maybe_grow(BUF_PARAMS(eff), EFF_ALEN(len)); + eff_map = afl_realloc(AFL_BUF_PARAM(eff), EFF_ALEN(len)); + if (unlikely(!eff_map)) { PFATAL("alloc"); } eff_map[0] = 1; if (EFF_APOS(len - 1) != 0) { @@ -1557,7 +1554,8 @@ skip_interest: orig_hit_cnt = new_hit_cnt; - ex_tmp = ck_maybe_grow(BUF_PARAMS(ex), len + MAX_DICT_FILE); + ex_tmp = afl_realloc(AFL_BUF_PARAM(ex), len + MAX_DICT_FILE); + if (unlikely(!ex_tmp)) { PFATAL("alloc"); } for (i = 0; i <= (u32)len; ++i) { @@ -1733,7 +1731,8 @@ custom_mutator_stage: fd = open(target->fname, O_RDONLY); if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); } - new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), target->len); + new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), target->len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } ck_read(fd, new_buf, target->len, target->fname); close(fd); @@ -1908,7 +1907,8 @@ havoc_stage: temp_len = new_len; if (out_buf != custom_havoc_buf) { - ck_maybe_grow(BUF_PARAMS(out), temp_len); + afl_realloc(AFL_BUF_PARAM(out), temp_len); + if (unlikely(!afl->out_buf)) { PFATAL("alloc"); } memcpy(out_buf, custom_havoc_buf, temp_len); } @@ -2147,7 +2147,8 @@ havoc_stage: clone_to = rand_below(afl, temp_len); new_buf = - ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); + afl_realloc(AFL_BUF_PARAM(out_scratch), temp_len + clone_len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } /* Head */ @@ -2172,7 +2173,7 @@ havoc_stage: memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, temp_len - clone_to); - swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); + afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); out_buf = new_buf; new_buf = NULL; temp_len += clone_len; @@ -2287,7 +2288,8 @@ havoc_stage: if (temp_len + extra_len >= MAX_FILE) { break; } - out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len); + out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len + extra_len); + if (unlikely(!out_buf)) { PFATAL("alloc"); } /* Tail */ memmove(out_buf + insert_at + extra_len, out_buf + insert_at, @@ -2343,7 +2345,8 @@ havoc_stage: } u32 new_len = target->len; - u8 *new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), new_len); + u8 *new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), new_len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } ck_read(fd, new_buf, new_len, target->fname); @@ -2383,7 +2386,8 @@ havoc_stage: clone_to = rand_below(afl, temp_len); u8 *temp_buf = - ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len); + afl_realloc(AFL_BUF_PARAM(out_scratch), temp_len + clone_len); + if (unlikely(!temp_buf)) { PFATAL("alloc"); } /* Head */ @@ -2397,7 +2401,7 @@ havoc_stage: memcpy(temp_buf + clone_to + clone_len, out_buf + clone_to, temp_len - clone_to); - swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); + afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); out_buf = temp_buf; temp_len += clone_len; @@ -2418,7 +2422,8 @@ havoc_stage: /* out_buf might have been mangled a bit, so let's restore it to its original size and shape. */ - out_buf = ck_maybe_grow(BUF_PARAMS(out), len); + out_buf = afl_realloc(AFL_BUF_PARAM(out), len); + if (unlikely(!out_buf)) { PFATAL("alloc"); } temp_len = len; memcpy(out_buf, in_buf, len); @@ -2513,7 +2518,8 @@ retry_splicing: if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); } - new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), target->len); + new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } ck_read(fd, new_buf, target->len, target->fname); @@ -2535,10 +2541,11 @@ retry_splicing: len = target->len; memcpy(new_buf, in_buf, split_at); - swap_bufs(BUF_PARAMS(in), BUF_PARAMS(in_scratch)); + afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); in_buf = new_buf; - out_buf = ck_maybe_grow(BUF_PARAMS(out), len); + out_buf = afl_realloc(AFL_BUF_PARAM(out), len); + if (unlikely(!out_buf)) { PFATAL("alloc"); } memcpy(out_buf, in_buf, len); goto custom_mutator_stage; @@ -2679,7 +2686,8 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { single byte anyway, so it wouldn't give us any performance or memory usage benefits. */ - out_buf = ck_maybe_grow(BUF_PARAMS(out), len); + out_buf = afl_realloc(AFL_BUF_PARAM(out), len); + if (unlikely(!out_buf)) { PFATAL("alloc"); } afl->subseq_tmouts = 0; @@ -3001,7 +3009,8 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { /* Initialize effector map for the next step (see comments below). Always flag first and last byte as doing something. */ - eff_map = ck_maybe_grow(BUF_PARAMS(eff), EFF_ALEN(len)); + eff_map = afl_realloc(AFL_BUF_PARAM(eff), EFF_ALEN(len)); + if (unlikely(!eff_map)) { PFATAL("alloc"); } eff_map[0] = 1; if (EFF_APOS(len - 1) != 0) { @@ -3758,7 +3767,8 @@ skip_interest: orig_hit_cnt = new_hit_cnt; - ex_tmp = ck_maybe_grow(BUF_PARAMS(ex), len + MAX_DICT_FILE); + ex_tmp = afl_realloc(AFL_BUF_PARAM(ex), len + MAX_DICT_FILE); + if (unlikely(!ex_tmp)) { PFATAL("alloc"); } for (i = 0; i <= (u32)len; ++i) { @@ -4196,8 +4206,9 @@ pacemaker_fuzzing: clone_to = rand_below(afl, temp_len); - new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), - temp_len + clone_len); + new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), + temp_len + clone_len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } /* Head */ @@ -4223,7 +4234,7 @@ pacemaker_fuzzing: memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, temp_len - clone_to); - swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); + afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); out_buf = new_buf; temp_len += clone_len; MOpt_globals.cycles_v2[STAGE_Clone75] += 1; @@ -4340,7 +4351,8 @@ pacemaker_fuzzing: if (temp_len + extra_len >= MAX_FILE) break; - out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len); + out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len + extra_len); + if (unlikely(!out_buf)) { PFATAL("alloc"); } /* Tail */ memmove(out_buf + insert_at + extra_len, out_buf + insert_at, @@ -4373,7 +4385,8 @@ pacemaker_fuzzing: /* out_buf might have been mangled a bit, so let's restore it to its original size and shape. */ - out_buf = ck_maybe_grow(BUF_PARAMS(out), len); + out_buf = afl_realloc(AFL_BUF_PARAM(out), len); + if (unlikely(!out_buf)) { PFATAL("alloc"); } temp_len = len; memcpy(out_buf, in_buf, len); @@ -4518,7 +4531,8 @@ pacemaker_fuzzing: if (fd < 0) { PFATAL("Unable to open '%s'", target->fname); } - new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), target->len); + new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } ck_read(fd, new_buf, target->len, target->fname); @@ -4545,9 +4559,10 @@ pacemaker_fuzzing: len = target->len; memcpy(new_buf, in_buf, split_at); - swap_bufs(BUF_PARAMS(in), BUF_PARAMS(in_scratch)); + afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); in_buf = new_buf; - out_buf = ck_maybe_grow(BUF_PARAMS(out), len); + out_buf = afl_realloc(AFL_BUF_PARAM(out), len); + if (unlikely(!out_buf)) { PFATAL("alloc"); } memcpy(out_buf, in_buf, len); goto havoc_stage_puppet; @@ -4880,5 +4895,3 @@ u8 fuzz_one(afl_state_t *afl) { } -#undef BUF_PARAMS - diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index a077469e..e540f548 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -40,9 +40,7 @@ static void *unsupported(afl_state_t *afl, unsigned int seed) { /* sorry for this makro... it just fills in `&py_mutator->something_buf, &py_mutator->something_size`. */ - #define BUF_PARAMS(name) \ - (void **)&((py_mutator_t *)py_mutator)->name##_buf, \ - &((py_mutator_t *)py_mutator)->name##_size + #define BUF_PARAMS(name) (void **)&((py_mutator_t *)py_mutator)->name##_buf static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf, u8 *add_buf, size_t add_buf_size, size_t max_size) { @@ -97,7 +95,8 @@ static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf, mutated_size = PyByteArray_Size(py_value); - *out_buf = ck_maybe_grow(BUF_PARAMS(fuzz), mutated_size); + *out_buf = afl_realloc(BUF_PARAMS(fuzz), mutated_size); + if (unlikely(!out_buf)) { PFATAL("alloc"); } memcpy(*out_buf, PyByteArray_AsString(py_value), mutated_size); Py_DECREF(py_value); @@ -317,7 +316,6 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, mutator = ck_alloc(sizeof(struct custom_mutator)); mutator->post_process_buf = NULL; - mutator->post_process_size = 0; mutator->name = module_name; ACTF("Loading Python mutator library from '%s'...", module_name); @@ -419,7 +417,11 @@ size_t post_process_py(void *py_mutator, u8 *buf, size_t buf_size, py_out_buf_size = PyByteArray_Size(py_value); - ck_maybe_grow(BUF_PARAMS(post_process), py_out_buf_size); + if (unlikely(!afl_realloc(BUF_PARAMS(post_process), py_out_buf_size))) { + + PFATAL("alloc"); + + } memcpy(py->post_process_buf, PyByteArray_AsString(py_value), py_out_buf_size); @@ -527,7 +529,8 @@ size_t trim_py(void *py_mutator, u8 **out_buf) { if (py_value != NULL) { ret = PyByteArray_Size(py_value); - *out_buf = ck_maybe_grow(BUF_PARAMS(trim), ret); + *out_buf = afl_realloc(BUF_PARAMS(trim), ret); + if (unlikely(!out_buf)) { PFATAL("alloc"); } memcpy(*out_buf, PyByteArray_AsString(py_value), ret); Py_DECREF(py_value); @@ -592,7 +595,8 @@ size_t havoc_mutation_py(void *py_mutator, u8 *buf, size_t buf_size, } else { /* A new buf is needed... */ - *out_buf = ck_maybe_grow(BUF_PARAMS(havoc), mutated_size); + *out_buf = afl_realloc(BUF_PARAMS(havoc), mutated_size); + if (unlikely(!out_buf)) { PFATAL("alloc"); } } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index f35df914..0c472845 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -26,8 +26,6 @@ #include #include -#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size - /* Mark deterministic checks as done for a particular queue entry. We use the .state file to avoid repeating deterministic fuzzing when resuming aborted scans. */ @@ -248,8 +246,9 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { } - struct queue_entry **queue_buf = ck_maybe_grow( - BUF_PARAMS(queue), afl->queued_paths * sizeof(struct queue_entry *)); + struct queue_entry **queue_buf = afl_realloc( + AFL_BUF_PARAM(queue), afl->queued_paths * sizeof(struct queue_entry *)); + if (unlikely(!queue_buf)) { PFATAL("alloc"); } queue_buf[afl->queued_paths - 1] = q; afl->last_path_time = get_cur_time(); diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index f21dd0b0..1ae6ab54 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -313,8 +313,6 @@ static unsigned long long strntoull(const char *str, size_t sz, char **end, } -#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size - static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u64 pattern, u64 repl, u64 o_pattern, u32 idx, u8 *orig_buf, u8 *buf, u32 len, u8 do_reverse, @@ -358,7 +356,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, size_t old_len = endptr - buf_8; size_t num_len = snprintf(NULL, 0, "%lld", num); - u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), len + num_len); + u8 *new_buf = afl_realloc((void **)&afl->out_scratch_buf, len + num_len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } memcpy(new_buf, buf, idx); snprintf(new_buf + idx, num_len, "%lld", num); @@ -371,7 +370,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, size_t old_len = endptr - buf_8; size_t num_len = snprintf(NULL, 0, "%llu", unum); - u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), len + num_len); + u8 *new_buf = afl_realloc((void **)&afl->out_scratch_buf, len + num_len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } memcpy(new_buf, buf, idx); snprintf(new_buf + idx, num_len, "%llu", unum); diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index d3f823c9..d71ec339 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -135,8 +135,6 @@ write_to_testcase(afl_state_t *afl, void *mem, u32 len) { } -#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size - /* The same, but with an adjustable gap. Used for trimming. */ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at, @@ -149,7 +147,8 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at, This memory is used to carry out the post_processing(if present) after copying the testcase by removing the gaps. This can break though */ - u8 *mem_trimmed = ck_maybe_grow(BUF_PARAMS(out_scratch), len - skip_len + 1); + u8 *mem_trimmed = afl_realloc(AFL_BUF_PARAM(out_scratch), len - skip_len + 1); + if (unlikely(!mem_trimmed)) { PFATAL("alloc"); } ssize_t new_size = len - skip_len; void * new_mem = mem; @@ -288,8 +287,6 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at, } -#undef BUF_PARAMS - /* Calibrate a new test case. This is done when processing the input directory to warn about flaky or otherwise problematic test cases early on; and when new paths are discovered to detect variable behavior and so on. */ diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index d4de91a4..e68e7786 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -421,13 +421,13 @@ void afl_state_deinit(afl_state_t *afl) { if (afl->pass_stats) { ck_free(afl->pass_stats); } if (afl->orig_cmp_map) { ck_free(afl->orig_cmp_map); } - if (afl->queue_buf) { free(afl->queue_buf); } - if (afl->out_buf) { free(afl->out_buf); } - if (afl->out_scratch_buf) { free(afl->out_scratch_buf); } - if (afl->eff_buf) { free(afl->eff_buf); } - if (afl->in_buf) { free(afl->in_buf); } - if (afl->in_scratch_buf) { free(afl->in_scratch_buf); } - if (afl->ex_buf) { free(afl->ex_buf); } + afl_free(afl->queue_buf); + afl_free(afl->out_buf); + afl_free(afl->out_scratch_buf); + afl_free(afl->eff_buf); + afl_free(afl->in_buf); + afl_free(afl->in_scratch_buf); + afl_free(afl->ex_buf); ck_free(afl->virgin_bits); ck_free(afl->virgin_tmout); -- cgit v1.2.3 From 1a94cfe2af023a33c0a0defa5933541731136922 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 18 Aug 2020 01:31:40 +0200 Subject: moved autodict extras away from extras_a --- src/afl-forkserver.c | 4 +-- src/afl-fuzz-extras.c | 98 ++++++++++++++++++++++++++++++++++++++++----------- src/afl-fuzz-state.c | 2 +- 3 files changed, 80 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 25983f26..85450e4a 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -630,7 +630,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if ((status & FS_OPT_AUTODICT) == FS_OPT_AUTODICT) { - if (fsrv->autodict_func == NULL || fsrv->afl_ptr == NULL) { + if (fsrv->add_extra_func == NULL || fsrv->afl_ptr == NULL) { // this is not afl-fuzz - we deny and return if (fsrv->use_shmem_fuzz) { @@ -715,7 +715,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, while (offset < (u32)status && (u8)dict[offset] + offset < (u32)status) { - fsrv->autodict_func(fsrv->afl_ptr, dict + offset + 1, + fsrv->add_extra_func(fsrv->afl_ptr, dict + offset + 1, (u8)dict[offset]); offset += (1 + dict[offset]); count++; diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 88262a98..77a6c05e 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -227,6 +227,38 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len, } +static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len, u8 *dir) { + + u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX]; + + if (!afl->extras_cnt) { + FATAL("No usable files in '%s'", dir); } + + qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data), + compare_extras_len); + + OKF("Loaded %u extra tokens, size range %s to %s.", afl->extras_cnt, + stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), min_len), + stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), max_len)); + + if (max_len > 32) { + + WARNF("Some tokens are relatively large (%s) - consider trimming.", + stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), max_len)); + + } + + if (afl->extras_cnt > MAX_DET_EXTRAS) { + + WARNF("More than %d tokens - will use them probabilistically.", + MAX_DET_EXTRAS); + + } + +} + + + /* Read extras from the extras directory and sort them by size. */ void load_extras(afl_state_t *afl, u8 *dir) { @@ -256,7 +288,8 @@ void load_extras(afl_state_t *afl, u8 *dir) { if (errno == ENOTDIR) { load_extras_file(afl, dir, &min_len, &max_len, dict_level); - goto check_and_sort; + extras_check_and_sort(afl, min_len, max_len, dir); + return; } @@ -321,44 +354,67 @@ void load_extras(afl_state_t *afl, u8 *dir) { closedir(d); -check_and_sort: + extras_check_and_sort(afl, min_len, max_len, dir); - if (!afl->extras_cnt) { FATAL("No usable files in '%s'", dir); } +} - qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data), - compare_extras_len); +/* Helper function for maybe_add_auto(afl, ) */ - OKF("Loaded %u extra tokens, size range %s to %s.", afl->extras_cnt, - stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), min_len), - stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), max_len)); +static inline u8 memcmp_nocase(u8 *m1, u8 *m2, u32 len) { - if (max_len > 32) { + while (len--) { - WARNF("Some tokens are relatively large (%s) - consider trimming.", - stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), max_len)); + if (tolower(*(m1++)) ^ tolower(*(m2++))) { return 1; } } - if (afl->extras_cnt > MAX_DET_EXTRAS) { + return 0; - WARNF("More than %d tokens - will use them probabilistically.", - MAX_DET_EXTRAS); +} - } +/* Adds a new extra / dict entry. */ +void add_extra(afl_state_t *afl, u8 *mem, u32 len) { -} + u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX]; -/* Helper function for maybe_add_auto(afl, ) */ + if (len > MAX_DICT_FILE) { -static inline u8 memcmp_nocase(u8 *m1, u8 *m2, u32 len) { + FATAL( + "Extra '%.*s' is too big (%s, limit is %s)", (int)len, mem, + stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len), + stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE)); - while (len--) { + } else if (len > 32) { - if (tolower(*(m1++)) ^ tolower(*(m2++))) { return 1; } + WARNF( + "Extra '%.*s' is pretty large, consider trimming.", (int)len, mem + ); } - return 0; + afl->extras = + afl_realloc((void **)&afl->extras, + (afl->extras_cnt + 1) * sizeof(struct extra_data)); + if (unlikely(!afl->extras)) { PFATAL("alloc"); } + + afl->extras[afl->extras_cnt].data = ck_alloc(len); + afl->extras[afl->extras_cnt].len = len; + + memcpy(afl->extras[afl->extras_cnt].data, mem, len); + + afl->extras_cnt++; + + qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data), + compare_extras_len); + + /* We only want to print this once */ + + if (afl->extras_cnt == MAX_DET_EXTRAS + 1) { + + WARNF("More than %d tokens - will use them probabilistically.", + MAX_DET_EXTRAS); + + } } diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index e68e7786..7e9f15b7 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -114,7 +114,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->fsrv.map_size = map_size; // afl_state_t is not available in forkserver.c afl->fsrv.afl_ptr = (void *)afl; - afl->fsrv.autodict_func = (void (*)(void *, u8 *, u32)) & maybe_add_auto; + afl->fsrv.add_extra_func = (void (*)(void *, u8 *, u32)) &add_extra; afl->cal_cycles = CAL_CYCLES; afl->cal_cycles_long = CAL_CYCLES_LONG; -- cgit v1.2.3 From b504b9313a47c597296a2dab4fd8a591d93242b4 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 18 Aug 2020 01:36:49 +0200 Subject: code-format, changelog --- src/afl-forkserver.c | 2 +- src/afl-fuzz-extras.c | 26 ++++++++++---------------- src/afl-fuzz-state.c | 2 +- 3 files changed, 12 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 85450e4a..8277116b 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -716,7 +716,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, (u8)dict[offset] + offset < (u32)status) { fsrv->add_extra_func(fsrv->afl_ptr, dict + offset + 1, - (u8)dict[offset]); + (u8)dict[offset]); offset += (1 + dict[offset]); count++; diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 77a6c05e..094c30b9 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -227,12 +227,12 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len, } -static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len, u8 *dir) { +static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len, + u8 *dir) { u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX]; - if (!afl->extras_cnt) { - FATAL("No usable files in '%s'", dir); } + if (!afl->extras_cnt) { FATAL("No usable files in '%s'", dir); } qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data), compare_extras_len); @@ -257,8 +257,6 @@ static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len, u8 } - - /* Read extras from the extras directory and sort them by size. */ void load_extras(afl_state_t *afl, u8 *dir) { @@ -379,22 +377,18 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { if (len > MAX_DICT_FILE) { - FATAL( - "Extra '%.*s' is too big (%s, limit is %s)", (int)len, mem, - stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len), - stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE)); + FATAL("Extra '%.*s' is too big (%s, limit is %s)", (int)len, mem, + stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len), + stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE)); } else if (len > 32) { - WARNF( - "Extra '%.*s' is pretty large, consider trimming.", (int)len, mem - ); + WARNF("Extra '%.*s' is pretty large, consider trimming.", (int)len, mem); } - afl->extras = - afl_realloc((void **)&afl->extras, - (afl->extras_cnt + 1) * sizeof(struct extra_data)); + afl->extras = afl_realloc((void **)&afl->extras, + (afl->extras_cnt + 1) * sizeof(struct extra_data)); if (unlikely(!afl->extras)) { PFATAL("alloc"); } afl->extras[afl->extras_cnt].data = ck_alloc(len); @@ -410,7 +404,7 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { /* We only want to print this once */ if (afl->extras_cnt == MAX_DET_EXTRAS + 1) { - + WARNF("More than %d tokens - will use them probabilistically.", MAX_DET_EXTRAS); diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 7e9f15b7..dd0e316c 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -114,7 +114,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->fsrv.map_size = map_size; // afl_state_t is not available in forkserver.c afl->fsrv.afl_ptr = (void *)afl; - afl->fsrv.add_extra_func = (void (*)(void *, u8 *, u32)) &add_extra; + afl->fsrv.add_extra_func = (void (*)(void *, u8 *, u32)) & add_extra; afl->cal_cycles = CAL_CYCLES; afl->cal_cycles_long = CAL_CYCLES_LONG; -- cgit v1.2.3 From 47878f697485e0543ce9e5d81369aa1ecc56e55e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 21 Aug 2020 23:33:35 +0200 Subject: add execs_done to plot file --- src/afl-fuzz-stats.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index aeb290bd..0ce35cb7 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -206,7 +206,8 @@ void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) { afl->plot_prev_qc == afl->queue_cycle && afl->plot_prev_uc == afl->unique_crashes && afl->plot_prev_uh == afl->unique_hangs && - afl->plot_prev_md == afl->max_depth) || + afl->plot_prev_md == afl->max_depth && + afl->plot_prev_ed == afl->fsrv.total_execs) || unlikely(!afl->queue_cycle) || unlikely(get_cur_time() - afl->start_time <= 60)) { @@ -222,6 +223,7 @@ void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) { afl->plot_prev_uc = afl->unique_crashes; afl->plot_prev_uh = afl->unique_hangs; afl->plot_prev_md = afl->max_depth; + afl->plot_prev_ed = afl->fsrv.total_execs; /* Fields in the file: @@ -229,12 +231,13 @@ void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) { favored_not_fuzzed, afl->unique_crashes, afl->unique_hangs, afl->max_depth, execs_per_sec */ - fprintf(afl->fsrv.plot_file, - "%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f\n", - get_cur_time() / 1000, afl->queue_cycle - 1, afl->current_entry, - afl->queued_paths, afl->pending_not_fuzzed, afl->pending_favored, - bitmap_cvg, afl->unique_crashes, afl->unique_hangs, afl->max_depth, - eps); /* ignore errors */ + fprintf( + afl->fsrv.plot_file, + "%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f, %llu\n", + get_cur_time() / 1000, afl->queue_cycle - 1, afl->current_entry, + afl->queued_paths, afl->pending_not_fuzzed, afl->pending_favored, + bitmap_cvg, afl->unique_crashes, afl->unique_hangs, afl->max_depth, eps, + afl->plot_prev_ed); /* ignore errors */ fflush(afl->fsrv.plot_file); -- cgit v1.2.3 From 5ec91fce23ddf3b81076ea4cb4a4553c9c302c3e Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 21 Aug 2020 23:03:08 +0200 Subject: fix for bad free (#520) --- src/afl-fuzz-extras.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 094c30b9..1452c55e 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -627,7 +627,7 @@ void destroy_extras(afl_state_t *afl) { } - ck_free(afl->extras); + afl_free(afl->extras); } -- cgit v1.2.3 From c4f71ab201da991fd16b2691f76020bfdb6459a4 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 22 Aug 2020 10:01:45 +0200 Subject: enable autodict for cmplog compile, it is ensure not be used in the forkserver --- src/afl-forkserver.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 8277116b..52a14602 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -115,6 +115,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->out_file = NULL; fsrv_to->init_child_func = fsrv_exec_child; + //Note: do not copy ->add_extra_func list_append(&fsrv_list, fsrv_to); -- cgit v1.2.3 From 1301552101af899557a93a7535d8a57874fe6edf Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sun, 23 Aug 2020 01:48:36 +0200 Subject: added AFL_MAX_DET_EXTRAS env var --- src/afl-forkserver.c | 2 +- src/afl-fuzz-extras.c | 8 ++++---- src/afl-fuzz-one.c | 16 ++++++++-------- src/afl-fuzz-state.c | 7 +++++++ src/afl-fuzz.c | 19 +++++++++++++++++-- 5 files changed, 37 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 52a14602..9d9e81cd 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -115,7 +115,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->out_file = NULL; fsrv_to->init_child_func = fsrv_exec_child; - //Note: do not copy ->add_extra_func + // Note: do not copy ->add_extra_func list_append(&fsrv_list, fsrv_to); diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 1452c55e..03c5152a 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -248,10 +248,10 @@ static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len, } - if (afl->extras_cnt > MAX_DET_EXTRAS) { + if (afl->extras_cnt > afl->max_det_extras) { WARNF("More than %d tokens - will use them probabilistically.", - MAX_DET_EXTRAS); + afl->max_det_extras); } @@ -403,10 +403,10 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { /* We only want to print this once */ - if (afl->extras_cnt == MAX_DET_EXTRAS + 1) { + if (afl->extras_cnt == afl->max_det_extras + 1) { WARNF("More than %d tokens - will use them probabilistically.", - MAX_DET_EXTRAS); + afl->max_det_extras); } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 3bf0c195..c0c036db 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1509,13 +1509,13 @@ skip_interest: for (j = 0; j < afl->extras_cnt; ++j) { - /* Skip extras probabilistically if afl->extras_cnt > MAX_DET_EXTRAS. Also - skip them if there's no room to insert the payload, if the token + /* Skip extras probabilistically if afl->extras_cnt > AFL_MAX_DET_EXTRAS. + Also skip them if there's no room to insert the payload, if the token is redundant, or if its entire span has no bytes set in the effector map. */ - if ((afl->extras_cnt > MAX_DET_EXTRAS && - rand_below(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) || + if ((afl->extras_cnt > afl->max_det_extras && + rand_below(afl, afl->extras_cnt) >= afl->max_det_extras) || afl->extras[j].len > len - i || !memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) || !memchr(eff_map + EFF_APOS(i), 1, @@ -3722,13 +3722,13 @@ skip_interest: for (j = 0; j < afl->extras_cnt; ++j) { - /* Skip extras probabilistically if afl->extras_cnt > MAX_DET_EXTRAS. Also - skip them if there's no room to insert the payload, if the token + /* Skip extras probabilistically if afl->extras_cnt > AFL_MAX_DET_EXTRAS. + Also skip them if there's no room to insert the payload, if the token is redundant, or if its entire span has no bytes set in the effector map. */ - if ((afl->extras_cnt > MAX_DET_EXTRAS && - rand_below(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) || + if ((afl->extras_cnt > afl->max_det_extras && + rand_below(afl, afl->extras_cnt) >= afl->max_det_extras) || afl->extras[j].len > len - i || !memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) || !memchr(eff_map + EFF_APOS(i), 1, diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index dd0e316c..74798584 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -349,6 +349,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_preload = (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_MAX_DET_EXTRAS", + + afl_environment_variable_len)) { + + afl->afl_env.afl_max_det_extras = + (u8 *)get_afl_env(afl_environment_variables[i]); + } } else { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 5dd092f2..664cc076 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -177,6 +177,8 @@ static void usage(u8 *argv0, int more_help) { "AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n" "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n" " the target was compiled for\n" + "AFL_MAX_DET_EXTRAS: if the dict/extras file contains more tokens than this threshold,\n" + " the tokens will sometimes be skipped during fuzzing.\n" "AFL_NO_AFFINITY: do not check for an unused cpu core to use for fuzzing\n" "AFL_NO_ARITH: skip arithmetic mutations in deterministic stage\n" "AFL_NO_CPU_RED: avoid red color for showing very high cpu usage\n" @@ -949,8 +951,21 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->afl_env.afl_hang_tmout) { - afl->hang_tmout = atoi(afl->afl_env.afl_hang_tmout); - if (!afl->hang_tmout) { FATAL("Invalid value of AFL_HANG_TMOUT"); } + s32 hang_tmout = atoi(afl->afl_env.afl_hang_tmout); + if (hang_tmout < 1) { FATAL("Invalid value for AFL_HANG_TMOUT"); } + afl->hang_tmout = (u32)hang_tmout; + + } + + if (afl->afl_env.afl_max_det_extras) { + + s32 max_det_extras = atoi(afl->afl_env.afl_max_det_extras); + if (max_det_extras < 1) { FATAL("Invalid value for AFL_MAX_DET_EXTRAS"); } + afl->max_det_extras = (u32)max_det_extras; + + } else { + + afl->max_det_extras = MAX_DET_EXTRAS; } -- cgit v1.2.3 From 425908a00cdcaa4d49a513d283431b8b6eed0486 Mon Sep 17 00:00:00 2001 From: Marius Muench Date: Sun, 23 Aug 2020 10:39:34 +0200 Subject: Option for specifying forkserver initialization timeout via environment variable (#522) * Addition of AFL_FORKSRV_INIT_TMOUT env var This commit introduces a new environment variable which allows to specify the timespan AFL should wait for initial contact with the forkserver. This is useful for fuzz-targets requiring a rather long setup time before the actual fuzzing can be started (e.g., unicorn). * add .swp files to .gitignore * Inherit init_tmout in afl_fsrv_init_dup Without this patch, the forkserver would spawn with a timeout of 0 in cmplog mode, leading to an immediate crash. Additionally, this commit removes a spurious whitespace. * Initialize afl->fsrv.init_tmout in afl_fsrv_init Not all afl-components will need the new AFL_FORKSRV_INIT_TMOUT environment variable. Hence, it's initialized to the safe "default" value from before in afl_fsrv_init now. --- src/afl-forkserver.c | 6 ++++-- src/afl-fuzz-state.c | 7 +++++++ src/afl-fuzz.c | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 9d9e81cd..51734579 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -79,6 +79,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) { fsrv->use_stdin = 1; fsrv->no_unlink = 0; fsrv->exec_tmout = EXEC_TIMEOUT; + fsrv->init_tmout = EXEC_TIMEOUT * FORK_WAIT_MULT; fsrv->mem_limit = MEM_LIMIT; fsrv->out_file = NULL; @@ -101,6 +102,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->out_fd = from->out_fd; fsrv_to->dev_null_fd = from->dev_null_fd; fsrv_to->exec_tmout = from->exec_tmout; + fsrv_to->init_tmout = from->init_tmout; fsrv_to->mem_limit = from->mem_limit; fsrv_to->map_size = from->map_size; fsrv_to->support_shmem_fuzz = from->support_shmem_fuzz; @@ -519,13 +521,13 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, u32 time_ms = read_s32_timed(fsrv->fsrv_st_fd, &status, - fsrv->exec_tmout * FORK_WAIT_MULT, stop_soon_p); + fsrv->init_tmout, stop_soon_p); if (!time_ms) { kill(fsrv->fsrv_pid, SIGKILL); - } else if (time_ms > fsrv->exec_tmout * FORK_WAIT_MULT) { + } else if (time_ms > fsrv->init_tmout) { fsrv->last_run_timed_out = 1; kill(fsrv->fsrv_pid, SIGKILL); diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 74798584..a8db8578 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -356,6 +356,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_max_det_extras = (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_FORKSRV_INIT_TMOUT", + + afl_environment_variable_len)) { + + afl->afl_env.afl_forksrv_init_tmout = + (u8 *) get_afl_env(afl_environment_variables[i]); + } } else { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 664cc076..ae5cb087 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -173,6 +173,7 @@ static void usage(u8 *argv0, int more_help) { "AFL_FAST_CAL: limit the calibration stage to three cycles for speedup\n" "AFL_FORCE_UI: force showing the status screen (for virtual consoles)\n" "AFL_HANG_TMOUT: override timeout value (in milliseconds)\n" + "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n" "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n" "AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n" "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n" @@ -969,6 +970,22 @@ int main(int argc, char **argv_orig, char **envp) { } + if (afl->afl_env.afl_forksrv_init_tmout) { + + afl->fsrv.init_tmout = atoi(afl->afl_env.afl_forksrv_init_tmout); + if (!afl->fsrv.init_tmout) { + + FATAL("Invalid value of AFL_FORKSRV_INIT_TMOUT"); + + } + + } else { + + afl->fsrv.init_tmout = afl->fsrv.exec_tmout * FORK_WAIT_MULT; + + } + + if (afl->non_instrumented_mode == 2 && afl->no_forkserver) { FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive"); -- cgit v1.2.3 From e2b54bfa0540d074423260bec01a544e9beda1df Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sun, 23 Aug 2020 10:40:46 +0200 Subject: code format --- src/afl-forkserver.c | 5 ++--- src/afl-fuzz-state.c | 2 +- src/afl-fuzz.c | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 51734579..c496975f 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -519,9 +519,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, rlen = 0; if (fsrv->exec_tmout) { - u32 time_ms = - read_s32_timed(fsrv->fsrv_st_fd, &status, - fsrv->init_tmout, stop_soon_p); + u32 time_ms = read_s32_timed(fsrv->fsrv_st_fd, &status, fsrv->init_tmout, + stop_soon_p); if (!time_ms) { diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index a8db8578..577fc34f 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -361,7 +361,7 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl_environment_variable_len)) { afl->afl_env.afl_forksrv_init_tmout = - (u8 *) get_afl_env(afl_environment_variables[i]); + (u8 *)get_afl_env(afl_environment_variables[i]); } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index ae5cb087..1abd49d8 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -985,7 +985,6 @@ int main(int argc, char **argv_orig, char **envp) { } - if (afl->non_instrumented_mode == 2 && afl->no_forkserver) { FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive"); -- cgit v1.2.3 From 6184832ea98050c91cdefa5059e18e78c39b14de Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sun, 23 Aug 2020 10:59:56 +0200 Subject: added more env var docs, fsrv fixes for cmin, tmin --- src/afl-showmap.c | 10 ++++++++++ src/afl-tmin.c | 10 ++++++++++ 2 files changed, 20 insertions(+) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 47c615d8..2c20e419 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1036,6 +1036,16 @@ int main(int argc, char **argv_orig, char **envp) { } + if (getenv("AFL_FORKSRV_INIT_TMOUT")) { + + s32 forksrv_init_tmout = atoi(getenv("AFL_FORKSRV_INIT_TMOUT")); + if (forksrv_init_tmout < 1) { + FATAL("Bad value specified for AFL_FORKSRV_INIT_TMOUT"); + } + fsrv->init_tmout = (u32) forksrv_init_tmout; + + } + afl_fsrv_start(fsrv, use_argv, &stop_soon, get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0); map_size = fsrv->map_size; diff --git a/src/afl-tmin.c b/src/afl-tmin.c index b50d8597..a15a6079 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -1103,6 +1103,16 @@ int main(int argc, char **argv_orig, char **envp) { } SAYF("\n"); + + if (getenv("AFL_FORKSRV_INIT_TMOUT")) { + + s32 forksrv_init_tmout = atoi(getenv("AFL_FORKSRV_INIT_TMOUT")); + if (forksrv_init_tmout < 1) { + FATAL("Bad value specified for AFL_FORKSRV_INIT_TMOUT"); + } + fsrv->init_tmout = (u32) forksrv_init_tmout; + + } shm_fuzz = ck_alloc(sizeof(sharedmem_t)); -- cgit v1.2.3 From 4d9d52e3d9b202d5da999897a0e8c574f453cf7a Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sun, 23 Aug 2020 11:00:46 +0200 Subject: code format --- src/afl-showmap.c | 5 ++++- src/afl-tmin.c | 7 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 2c20e419..64b52479 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1040,9 +1040,12 @@ int main(int argc, char **argv_orig, char **envp) { s32 forksrv_init_tmout = atoi(getenv("AFL_FORKSRV_INIT_TMOUT")); if (forksrv_init_tmout < 1) { + FATAL("Bad value specified for AFL_FORKSRV_INIT_TMOUT"); + } - fsrv->init_tmout = (u32) forksrv_init_tmout; + + fsrv->init_tmout = (u32)forksrv_init_tmout; } diff --git a/src/afl-tmin.c b/src/afl-tmin.c index a15a6079..59269f45 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -1103,14 +1103,17 @@ int main(int argc, char **argv_orig, char **envp) { } SAYF("\n"); - + if (getenv("AFL_FORKSRV_INIT_TMOUT")) { s32 forksrv_init_tmout = atoi(getenv("AFL_FORKSRV_INIT_TMOUT")); if (forksrv_init_tmout < 1) { + FATAL("Bad value specified for AFL_FORKSRV_INIT_TMOUT"); + } - fsrv->init_tmout = (u32) forksrv_init_tmout; + + fsrv->init_tmout = (u32)forksrv_init_tmout; } -- cgit v1.2.3 From a1442bd1ac2be2fc20b90c37a71e7c3b997fd35b Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sun, 23 Aug 2020 11:21:49 +0200 Subject: no longer warns for prob. extras --- src/afl-fuzz-extras.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 03c5152a..2b9854d4 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -250,7 +250,7 @@ static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len, if (afl->extras_cnt > afl->max_det_extras) { - WARNF("More than %d tokens - will use them probabilistically.", + OKF("More than %d tokens - will use them probabilistically.", afl->max_det_extras); } @@ -370,7 +370,7 @@ static inline u8 memcmp_nocase(u8 *m1, u8 *m2, u32 len) { } -/* Adds a new extra / dict entry. */ +/* Adds a new extra / dict entry. Used for LTO autodict. */ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX]; @@ -405,7 +405,7 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { if (afl->extras_cnt == afl->max_det_extras + 1) { - WARNF("More than %d tokens - will use them probabilistically.", + OKF("More than %d tokens - will use them probabilistically.", afl->max_det_extras); } -- cgit v1.2.3 From b9b6f064297839103d8b2ae06accfda2a3dc6aa1 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 24 Aug 2020 12:04:29 +0200 Subject: Allow Large Extras (#523) * allow large extras * skipping large testcases again --- src/afl-fuzz-extras.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 2b9854d4..8cc2425f 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -319,8 +319,8 @@ void load_extras(afl_state_t *afl, u8 *dir) { if (st.st_size > MAX_DICT_FILE) { - FATAL( - "Extra '%s' is too big (%s, limit is %s)", fn, + WARNF( + "Extra '%s' is very big (%s, limit is %s)", fn, stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), st.st_size), stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE)); @@ -377,7 +377,7 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { if (len > MAX_DICT_FILE) { - FATAL("Extra '%.*s' is too big (%s, limit is %s)", (int)len, mem, + WARNF("Extra '%.*s' is very big (%s, limit is %s)", (int)len, mem, stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len), stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE)); -- cgit v1.2.3 From c7f0d3066875bca0ec28e9429df40293339dc05c Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 24 Aug 2020 17:32:41 +0200 Subject: added afl_custom_fuzz_count --- src/afl-forkserver.c | 2 +- src/afl-fuzz-extras.c | 4 +- src/afl-fuzz-mutators.c | 5 ++ src/afl-fuzz-one.c | 129 +++++++++++++++++++++++++++--------------------- src/afl-fuzz-python.c | 44 +++++++++++++++++ 5 files changed, 124 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index c496975f..72f3dc3b 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -634,7 +634,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (fsrv->add_extra_func == NULL || fsrv->afl_ptr == NULL) { - // this is not afl-fuzz - we deny and return + // this is not afl-fuzz - or it is cmplog - we deny and return if (fsrv->use_shmem_fuzz) { status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ); diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 8cc2425f..d6c368d1 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -251,7 +251,7 @@ static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len, if (afl->extras_cnt > afl->max_det_extras) { OKF("More than %d tokens - will use them probabilistically.", - afl->max_det_extras); + afl->max_det_extras); } @@ -406,7 +406,7 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { if (afl->extras_cnt == afl->max_det_extras + 1) { OKF("More than %d tokens - will use them probabilistically.", - afl->max_det_extras); + afl->max_det_extras); } diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 22578df9..d24b7db9 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -166,6 +166,11 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { } + /* "afl_custom_fuzz_count", optional */ + mutator->afl_custom_fuzz_count = dlsym(dh, "afl_custom_fuzz_count"); + if (!mutator->afl_custom_fuzz_count) + ACTF("optional symbol 'afl_custom_fuzz_count' not found."); + /* "afl_custom_deinit", optional for backward compatibility */ mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit"); if (!mutator->afl_custom_deinit) diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index c0c036db..03c0d3a1 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1672,7 +1672,7 @@ custom_mutator_stage: if (afl->stage_max < HAVOC_MIN) { afl->stage_max = HAVOC_MIN; } - const u32 max_seed_size = MAX_FILE; + const u32 max_seed_size = MAX_FILE, saved_max = afl->stage_max; orig_hit_cnt = afl->queued_paths + afl->unique_crashes; @@ -1680,104 +1680,119 @@ custom_mutator_stage: if (el->afl_custom_fuzz) { + if (el->afl_custom_fuzz_count) + afl->stage_max = el->afl_custom_fuzz_count(el->data, out_buf, len); + else + afl->stage_max = saved_max; + has_custom_fuzz = true; afl->stage_short = el->name_short; - for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; - ++afl->stage_cur) { + if (afl->stage_max) { - struct queue_entry *target; - u32 tid; - u8 * new_buf; + for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; + ++afl->stage_cur) { - retry_external_pick: - /* Pick a random other queue entry for passing to external API */ + struct queue_entry *target; + u32 tid; + u8 * new_buf; - do { + retry_external_pick: + /* Pick a random other queue entry for passing to external API */ - tid = rand_below(afl, afl->queued_paths); + do { - } while (tid == afl->current_entry && afl->queued_paths > 1); + tid = rand_below(afl, afl->queued_paths); - target = afl->queue; + } while (tid == afl->current_entry && afl->queued_paths > 1); - while (tid >= 100) { + target = afl->queue; - target = target->next_100; - tid -= 100; + while (tid >= 100) { - } - - while (tid--) { + target = target->next_100; + tid -= 100; - target = target->next; + } - } + while (tid--) { - /* Make sure that the target has a reasonable length. */ + target = target->next; - while (target && (target->len < 2 || target == afl->queue_cur) && - afl->queued_paths > 3) { + } - target = target->next; - ++afl->splicing_with; + /* Make sure that the target has a reasonable length. */ - } + while (target && (target->len < 2 || target == afl->queue_cur) && + afl->queued_paths > 3) { - if (!target) { goto retry_external_pick; } + target = target->next; + ++afl->splicing_with; - /* Read the additional testcase into a new buffer. */ - fd = open(target->fname, O_RDONLY); - if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); } + } - new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), target->len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - ck_read(fd, new_buf, target->len, target->fname); - close(fd); + if (!target) { goto retry_external_pick; } - u8 *mutated_buf = NULL; + /* Read the additional testcase into a new buffer. */ + fd = open(target->fname, O_RDONLY); + if (unlikely(fd < 0)) { - size_t mutated_size = - el->afl_custom_fuzz(el->data, out_buf, len, &mutated_buf, new_buf, - target->len, max_seed_size); + PFATAL("Unable to open '%s'", target->fname); - if (unlikely(!mutated_buf)) { + } - FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size); + new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), target->len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } + ck_read(fd, new_buf, target->len, target->fname); + close(fd); - } + u8 *mutated_buf = NULL; - if (mutated_size > 0) { + size_t mutated_size = + el->afl_custom_fuzz(el->data, out_buf, len, &mutated_buf, new_buf, + target->len, max_seed_size); - if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) { + if (unlikely(!mutated_buf)) { - goto abandon_entry; + FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size); } - /* If we're finding new stuff, let's run for a bit longer, limits - permitting. */ - - if (afl->queued_paths != havoc_queued) { + if (mutated_size > 0) { - if (perf_score <= afl->havoc_max_mult * 100) { + if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) { - afl->stage_max *= 2; - perf_score *= 2; + goto abandon_entry; } - havoc_queued = afl->queued_paths; + /* If we're finding new stuff, let's run for a bit longer, limits + permitting. */ + + if (afl->queued_paths != havoc_queued) { + + if (perf_score <= afl->havoc_max_mult * 100) { + + afl->stage_max *= 2; + perf_score *= 2; + + } + + havoc_queued = afl->queued_paths; + + } } - } + /* `(afl->)out_buf` may have been changed by the call to custom_fuzz + */ + /* TODO: Only do this when `mutated_buf` == `out_buf`? Branch vs + * Memcpy. + */ + memcpy(out_buf, in_buf, len); - /* `(afl->)out_buf` may have been changed by the call to custom_fuzz */ - /* TODO: Only do this when `mutated_buf` == `out_buf`? Branch vs Memcpy. - */ - memcpy(out_buf, in_buf, len); + } } diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index e540f548..68540dd7 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -347,6 +347,12 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, } + if (py_functions[PY_FUNC_FUZZ_COUNT]) { + + mutator->afl_custom_fuzz_count = fuzz_count_py; + + } + if (py_functions[PY_FUNC_POST_TRIM]) { mutator->afl_custom_post_trim = post_trim_py; @@ -477,6 +483,44 @@ s32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) { } +u32 fuzz_count_py(void *py_mutator, const u8 *buf, size_t buf_size) { + + PyObject *py_args, *py_value; + + py_args = PyTuple_New(1); + py_value = PyByteArray_FromStringAndSize(buf, buf_size); + if (!py_value) { + + Py_DECREF(py_args); + FATAL("Failed to convert arguments"); + + } + + PyTuple_SetItem(py_args, 0, py_value); + + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ_COUNT], py_args); + Py_DECREF(py_args); + + if (py_value != NULL) { + + #if PY_MAJOR_VERSION >= 3 + u32 retcnt = (u32)PyLong_AsLong(py_value); + #else + u32 retcnt = PyInt_AsLong(py_value); + #endif + Py_DECREF(py_value); + return retcnt; + + } else { + + PyErr_Print(); + FATAL("Call failed"); + + } + +} + s32 post_trim_py(void *py_mutator, u8 success) { PyObject *py_args, *py_value; -- cgit v1.2.3 From 6a34c5aa3e0a1da06a5268ecabfc92ab36ce96dc Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 24 Aug 2020 18:06:07 +0200 Subject: fix python implementation for new function --- src/afl-fuzz-python.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 68540dd7..32c8ac89 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -144,6 +144,7 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "fuzz"); if (!py_functions[PY_FUNC_FUZZ]) py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "mutate"); + py_functions[PY_FUNC_FUZZ_COUNT] = PyObject_GetAttrString(py_module, "fuzz_count"); if (!py_functions[PY_FUNC_FUZZ]) WARNF("fuzz function not found in python module"); py_functions[PY_FUNC_POST_PROCESS] = @@ -187,7 +188,7 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { // Implenting the havoc and queue API is optional for now if (PyErr_Occurred()) { PyErr_Print(); } - } else { + } else if (py_idx != PY_FUNC_FUZZ_COUNT) { if (PyErr_Occurred()) { PyErr_Print(); } fprintf(stderr, -- cgit v1.2.3 From 19eddbb0c76406db6d790681ef519c4d91e8814e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 24 Aug 2020 18:12:08 +0200 Subject: make py functions as optional as they are in the doc --- src/afl-fuzz-python.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 32c8ac89..adb92649 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -144,7 +144,8 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "fuzz"); if (!py_functions[PY_FUNC_FUZZ]) py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "mutate"); - py_functions[PY_FUNC_FUZZ_COUNT] = PyObject_GetAttrString(py_module, "fuzz_count"); + py_functions[PY_FUNC_FUZZ_COUNT] = + PyObject_GetAttrString(py_module, "fuzz_count"); if (!py_functions[PY_FUNC_FUZZ]) WARNF("fuzz function not found in python module"); py_functions[PY_FUNC_POST_PROCESS] = @@ -170,27 +171,20 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { if (!py_functions[py_idx] || !PyCallable_Check(py_functions[py_idx])) { - if (py_idx == PY_FUNC_POST_PROCESS) { - - // Implenting the post_process API is optional for now - if (PyErr_Occurred()) { PyErr_Print(); } - - } else if (py_idx >= PY_FUNC_INIT_TRIM && py_idx <= PY_FUNC_TRIM) { + if (py_idx >= PY_FUNC_INIT_TRIM && py_idx <= PY_FUNC_TRIM) { // Implementing the trim API is optional for now if (PyErr_Occurred()) { PyErr_Print(); } py_notrim = 1; - } else if ((py_idx >= PY_FUNC_HAVOC_MUTATION) && + } else if (py_idx >= PY_OPTIONAL) { - (py_idx <= PY_FUNC_QUEUE_NEW_ENTRY)) { + // Only _init and _deinit are not optional currently - // Implenting the havoc and queue API is optional for now if (PyErr_Occurred()) { PyErr_Print(); } - } else if (py_idx != PY_FUNC_FUZZ_COUNT) { + } else { - if (PyErr_Occurred()) { PyErr_Print(); } fprintf(stderr, "Cannot find/call function with index %d in external " "Python module.\n", -- cgit v1.2.3 From 1efc6e59b7cd2a3623ad3d75622e8bf107b3dc98 Mon Sep 17 00:00:00 2001 From: Sergio Paganoni Date: Mon, 24 Aug 2020 21:18:51 +0200 Subject: Added out_file value when using stdio (#524) --- src/afl-forkserver.c | 4 ++-- src/afl-fuzz-init.c | 13 +++++-------- 2 files changed, 7 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 72f3dc3b..93203cb2 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -941,7 +941,7 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { s32 fd = fsrv->out_fd; - if (fsrv->out_file) { + if (!fsrv->use_stdin) { if (fsrv->no_unlink) { @@ -964,7 +964,7 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { ck_write(fd, buf, len, fsrv->out_file); - if (!fsrv->out_file) { + if (fsrv->use_stdin) { if (ftruncate(fd, len)) { PFATAL("ftruncate() failed"); } lseek(fd, 0, SEEK_SET); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 350a8599..7b7ba006 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1841,24 +1841,21 @@ void setup_cmdline_file(afl_state_t *afl, char **argv) { void setup_stdio_file(afl_state_t *afl) { - u8 *fn; if (afl->file_extension) { - fn = alloc_printf("%s/.cur_input.%s", afl->tmp_dir, afl->file_extension); + afl->fsrv.out_file = alloc_printf("%s/.cur_input.%s", afl->tmp_dir, afl->file_extension); } else { - fn = alloc_printf("%s/.cur_input", afl->tmp_dir); + afl->fsrv.out_file = alloc_printf("%s/.cur_input", afl->tmp_dir); } - unlink(fn); /* Ignore errors */ + unlink(afl->fsrv.out_file); /* Ignore errors */ - afl->fsrv.out_fd = open(fn, O_RDWR | O_CREAT | O_EXCL, 0600); + afl->fsrv.out_fd = open(afl->fsrv.out_file, O_RDWR | O_CREAT | O_EXCL, 0600); - if (afl->fsrv.out_fd < 0) { PFATAL("Unable to create '%s'", fn); } - - ck_free(fn); + if (afl->fsrv.out_fd < 0) { PFATAL("Unable to create '%s'", afl->fsrv.out_file); } } -- cgit v1.2.3 From 9a6a32775f03e6fbd6df131742bee4c30bcd94a6 Mon Sep 17 00:00:00 2001 From: h1994st Date: Thu, 27 Aug 2020 00:32:53 -0400 Subject: Prevent afl-fuzz from modifying stage_max during fuzzing --- src/afl-fuzz-one.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 03c0d3a1..bf568c38 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1767,19 +1767,23 @@ custom_mutator_stage: } - /* If we're finding new stuff, let's run for a bit longer, limits - permitting. */ + if (!el->afl_custom_fuzz_count) { - if (afl->queued_paths != havoc_queued) { + /* If we're finding new stuff, let's run for a bit longer, limits + permitting. */ - if (perf_score <= afl->havoc_max_mult * 100) { + if (afl->queued_paths != havoc_queued) { - afl->stage_max *= 2; - perf_score *= 2; + if (perf_score <= afl->havoc_max_mult * 100) { - } + afl->stage_max *= 2; + perf_score *= 2; + + } - havoc_queued = afl->queued_paths; + havoc_queued = afl->queued_paths; + + } } -- cgit v1.2.3 From 41bb359428e4559821c95831f25c772d1a8403d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Hertzog?= Date: Fri, 28 Aug 2020 23:04:25 +0200 Subject: Fix various spelling errors (#532) All those spelling errors have been caught by lintian's built-in spellchecker: https://lintian.debian.org/tags/spelling-error-in-binary.html --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 1abd49d8..5ad2ace9 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -191,7 +191,7 @@ static void usage(u8 *argv0, int more_help) { "AFL_QUIET: suppress forkserver status messages\n" "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" "AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n" - "AFL_SKIP_BIN_CHECK: skip the check, if the target is an excutable\n" + "AFL_SKIP_BIN_CHECK: skip the check, if the target is an executable\n" "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n" "AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n" "AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n" -- cgit v1.2.3 From 4566bcf122c251c023abce0683666921bd4df755 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 31 Aug 2020 10:57:01 +0200 Subject: code-format --- src/afl-fuzz-init.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 7b7ba006..852fc3fb 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1843,7 +1843,8 @@ void setup_stdio_file(afl_state_t *afl) { if (afl->file_extension) { - afl->fsrv.out_file = alloc_printf("%s/.cur_input.%s", afl->tmp_dir, afl->file_extension); + afl->fsrv.out_file = + alloc_printf("%s/.cur_input.%s", afl->tmp_dir, afl->file_extension); } else { @@ -1851,11 +1852,15 @@ void setup_stdio_file(afl_state_t *afl) { } - unlink(afl->fsrv.out_file); /* Ignore errors */ + unlink(afl->fsrv.out_file); /* Ignore errors */ afl->fsrv.out_fd = open(afl->fsrv.out_file, O_RDWR | O_CREAT | O_EXCL, 0600); - if (afl->fsrv.out_fd < 0) { PFATAL("Unable to create '%s'", afl->fsrv.out_file); } + if (afl->fsrv.out_fd < 0) { + + PFATAL("Unable to create '%s'", afl->fsrv.out_file); + + } } -- cgit v1.2.3 From 81767287c31f454271f62c24a8331f382e14bc85 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 31 Aug 2020 13:02:40 +0200 Subject: improve documentation --- src/afl-fuzz.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 5ad2ace9..0df6c15c 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -178,8 +178,9 @@ static void usage(u8 *argv0, int more_help) { "AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n" "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n" " the target was compiled for\n" - "AFL_MAX_DET_EXTRAS: if the dict/extras file contains more tokens than this threshold,\n" - " the tokens will sometimes be skipped during fuzzing.\n" + "AFL_MAX_DET_EXTRAS: if more entries are in the dictionary list than this value\n" + " then they are randomly selected instead all of them being\n" + " used. Defaults to 200.\n" "AFL_NO_AFFINITY: do not check for an unused cpu core to use for fuzzing\n" "AFL_NO_ARITH: skip arithmetic mutations in deterministic stage\n" "AFL_NO_CPU_RED: avoid red color for showing very high cpu usage\n" -- cgit v1.2.3 From d2c9e4baa74210cf49243390fb3dabb29024ade4 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 31 Aug 2020 13:12:59 +0200 Subject: fix warnings and weird code insert --- src/afl-performance.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-performance.c b/src/afl-performance.c index 0c1697a8..a9d7cefa 100644 --- a/src/afl-performance.c +++ b/src/afl-performance.c @@ -72,12 +72,12 @@ void jump(afl_state_t *afl) { static const uint64_t JUMP[] = {0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c}; - int i, b; + size_t i, b; uint64_t s0 = 0; uint64_t s1 = 0; uint64_t s2 = 0; uint64_t s3 = 0; - for (i = 0; i < sizeof JUMP / sizeof *JUMP; i++) + for (i = 0; i < (sizeof(JUMP) / sizeof(*JUMP)); i++) for (b = 0; b < 64; b++) { if (JUMP[i] & UINT64_C(1) << b) { @@ -110,12 +110,12 @@ void long_jump(afl_state_t *afl) { static const uint64_t LONG_JUMP[] = {0x76e15d3efefdcbbf, 0xc5004e441c522fb3, 0x77710069854ee241, 0x39109bb02acbe635}; - int i, b; + size_t i, b; uint64_t s0 = 0; uint64_t s1 = 0; uint64_t s2 = 0; uint64_t s3 = 0; - for (i = 0; i < sizeof LONG_JUMP / sizeof *LONG_JUMP; i++) + for (i = 0; i < (sizeof(LONG_JUMP) / sizeof(*LONG_JUMP)); i++) for (b = 0; b < 64; b++) { if (LONG_JUMP[i] & UINT64_C(1) << b) { @@ -145,7 +145,7 @@ void long_jump(afl_state_t *afl) { u32 hash32(u8 *key, u32 len, u32 seed) { #else -u32 inline hash32(u8 *key, u32 len, u32 seed) { +inline u32 hash32(u8 *key, u32 len, u32 seed) { #endif @@ -157,7 +157,7 @@ u32 inline hash32(u8 *key, u32 len, u32 seed) { u64 hash64(u8 *key, u32 len, u64 seed) { #else -u64 inline hash64(u8 *key, u32 len, u64 seed) { +inline u64 hash64(u8 *key, u32 len, u64 seed) { #endif -- cgit v1.2.3 From 9e8b3f13e198dda74d4673866ffc4a37c976c05e Mon Sep 17 00:00:00 2001 From: domenukk Date: Mon, 31 Aug 2020 15:17:37 +0200 Subject: fixed warning on mac --- src/afl-as.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-as.c b/src/afl-as.c index 0ed47d8c..7d70bfcd 100644 --- a/src/afl-as.c +++ b/src/afl-as.c @@ -152,7 +152,7 @@ static void edit_params(int argc, char **argv) { /* The Apple case is a bit different... */ - if (!strcmp(argv[i], "-arch") && i + 1 < argc) { + if (!strcmp(argv[i], "-arch") && i + 1 < (u32)argc) { if (!strcmp(argv[i + 1], "x86_64")) use_64bit = 1; -- cgit v1.2.3 From 155ef8875a2ca544316bade52d4fc36c545d9856 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Mon, 31 Aug 2020 15:37:46 +0100 Subject: Fix few warnings for FreeBSD case. (#536) --- src/afl-fuzz-init.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 852fc3fb..102f04b9 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -256,18 +256,18 @@ void bind_to_free_cpu(afl_state_t *afl) { } - for (i = 0; i < proccount; i++) { + for (i = 0; i < (s32)proccount; i++) { #if defined(__FreeBSD__) if (!strcmp(procs[i].ki_comm, "idle")) continue; // fix when ki_oncpu = -1 - int oncpu; + s32 oncpu; oncpu = procs[i].ki_oncpu; if (oncpu == -1) oncpu = procs[i].ki_lastcpu; - if (oncpu != -1 && oncpu < sizeof(cpu_used) && procs[i].ki_pctcpu > 60) + if (oncpu != -1 && oncpu < (s32)sizeof(cpu_used) && procs[i].ki_pctcpu > 60) cpu_used[oncpu] = 1; #elif defined(__DragonFly__) -- cgit v1.2.3 From d7d8afa512bcc0c012fac3b624eeff7b5af65439 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 31 Aug 2020 17:54:21 +0200 Subject: fix afl-gcc help output --- src/afl-gcc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-gcc.c b/src/afl-gcc.c index 22e6be8e..97564aea 100644 --- a/src/afl-gcc.c +++ b/src/afl-gcc.c @@ -415,7 +415,7 @@ int main(int argc, char **argv) { "AFL_KEEP_ASSEMBLY: leave instrumented assembly files\n" "AFL_AS_FORCE_INSTRUMENT: force instrumentation for asm sources\n"; - if (argc == 2 && strcmp(argv[1], "-h") == 0) { + if (argc == 2 && strncmp(argv[1], "-h", 2) == 0) { printf("afl-cc" VERSION " by Michal Zalewski\n\n"); printf("%s \n\n", argv[0]); -- cgit v1.2.3 From 53e63e9ded202b63de19590bb3d265d2f01ee929 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 31 Aug 2020 18:28:36 +0200 Subject: added forkserver init timeout --- src/afl-showmap.c | 1 + src/afl-tmin.c | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 64b52479..e596c26e 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -637,6 +637,7 @@ static void usage(u8 *argv0) { " the target was compiled for\n" "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" "AFL_QUIET: do not print extra informational output\n", + "AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the target to come up, initially\n" argv0, MEM_LIMIT, doc_path); exit(1); diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 59269f45..f231cde9 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -846,6 +846,7 @@ static void usage(u8 *argv0) { " the target was compiled for\n" "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" "AFL_TMIN_EXACT: require execution paths to match for crashing inputs\n" + "AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the target to come up, initially\n" , argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path); -- cgit v1.2.3 From bea76b346ce278896d0b4a6f3b1d42e5c1c786c3 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 31 Aug 2020 18:29:45 +0200 Subject: fixed build error --- src/afl-showmap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index e596c26e..ae33cc48 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -636,9 +636,10 @@ static void usage(u8 *argv0) { "size\n" " the target was compiled for\n" "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" - "AFL_QUIET: do not print extra informational output\n", + "AFL_QUIET: do not print extra informational output\n" "AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the target to come up, initially\n" - argv0, MEM_LIMIT, doc_path); + + ,argv0, MEM_LIMIT, doc_path); exit(1); -- cgit v1.2.3 From e4de4e350009584f5cdb8cf4c47a79fff9358cad Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 31 Aug 2020 18:32:01 +0200 Subject: update gitignore --- src/afl-showmap.c | 8 ++++---- src/afl-tmin.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index ae33cc48..f4a7c336 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -636,10 +636,10 @@ static void usage(u8 *argv0) { "size\n" " the target was compiled for\n" "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" - "AFL_QUIET: do not print extra informational output\n" - "AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the target to come up, initially\n" - - ,argv0, MEM_LIMIT, doc_path); + "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during " + "startup (in milliseconds)\n" + "AFL_QUIET: do not print extra informational output\n", + argv0, MEM_LIMIT, doc_path); exit(1); diff --git a/src/afl-tmin.c b/src/afl-tmin.c index f231cde9..e1d08054 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -846,7 +846,7 @@ static void usage(u8 *argv0) { " the target was compiled for\n" "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" "AFL_TMIN_EXACT: require execution paths to match for crashing inputs\n" - "AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the target to come up, initially\n" + "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n" , argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path); -- cgit v1.2.3 From 9bbbec3fa8e18a84939ffd864ecfd9017af98aba Mon Sep 17 00:00:00 2001 From: Ahmad Hazimeh Date: Mon, 31 Aug 2020 18:39:50 +0200 Subject: Fixed stack use-after-return bug in strntoll --- src/afl-fuzz-redqueen.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 1ae6ab54..392b1909 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -282,7 +282,6 @@ static long long strntoll(const char *str, size_t sz, char **end, int base) { memcpy(buf, beg, sz); buf[sz] = '\0'; ret = strtoll(buf, end, base); - if (ret == LLONG_MIN || ret == LLONG_MAX) return ret; if (end) *end = (char *)beg + (*end - buf); return ret; -- cgit v1.2.3 From 6090bb1bca81229a4c6ae178e1cef0e35bd31a96 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Mon, 31 Aug 2020 20:33:56 +0200 Subject: better fix for #539 --- src/afl-fuzz-redqueen.c | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 1ae6ab54..73d00f9a 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -264,7 +264,8 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) { } -static long long strntoll(const char *str, size_t sz, char **end, int base) { +static int strntoll(const char *str, size_t sz, char **end, int base, + long long* out) { char buf[64]; long long ret; @@ -272,24 +273,25 @@ static long long strntoll(const char *str, size_t sz, char **end, int base) { for (; beg && sz && *beg == ' '; beg++, sz--) {}; - if (!sz || sz >= sizeof(buf)) { - - if (end) *end = (char *)str; - return 0; - - } + if (!sz) + return 1; + if (sz >= sizeof(buf)) + sz = sizeof(buf) -1; memcpy(buf, beg, sz); buf[sz] = '\0'; ret = strtoll(buf, end, base); - if (ret == LLONG_MIN || ret == LLONG_MAX) return ret; + if ((ret == LLONG_MIN || ret == LLONG_MAX) && errno == ERANGE) + return 1; if (end) *end = (char *)beg + (*end - buf); - return ret; + *out = ret; + + return 0; } -static unsigned long long strntoull(const char *str, size_t sz, char **end, - int base) { +static int strntoull(const char *str, size_t sz, char **end, int base, + unsigned long long* out) { char buf[64]; unsigned long long ret; @@ -298,18 +300,20 @@ static unsigned long long strntoull(const char *str, size_t sz, char **end, for (; beg && sz && *beg == ' '; beg++, sz--) ; - if (!sz || sz >= sizeof(buf)) { - - if (end) *end = (char *)str; - return 0; - - } + if (!sz) + return 1; + if (sz >= sizeof(buf)) + sz = sizeof(buf) -1; memcpy(buf, beg, sz); buf[sz] = '\0'; ret = strtoull(buf, end, base); + if (ret == ULLONG_MAX && errno == ERANGE) + return 1; if (end) *end = (char *)beg + (*end - buf); - return ret; + *out = ret; + + return 0; } @@ -336,17 +340,16 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u8 use_num = 0, use_unum = 0; unsigned long long unum; long long num; + if (afl->queue_cur->is_ascii) { endptr = buf_8; - num = strntoll(buf_8, len - idx, (char **)&endptr, 0); - if (endptr == buf_8) { + if (strntoll(buf_8, len - idx, (char **)&endptr, 0, &num)) { - unum = strntoull(buf_8, len - idx, (char **)&endptr, 0); - if (endptr == buf_8) use_unum = 1; + if (!strntoull(buf_8, len - idx, (char **)&endptr, 0, &unum)) + use_unum = 1; } else - use_num = 1; } -- cgit v1.2.3 From bd57784664a7de62c726a0fb2aaabd41471faa0c Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 31 Aug 2020 23:59:10 +0200 Subject: code format --- src/afl-fuzz-redqueen.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 73d00f9a..9a9ac33f 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -265,7 +265,7 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) { } static int strntoll(const char *str, size_t sz, char **end, int base, - long long* out) { + long long *out) { char buf[64]; long long ret; @@ -273,16 +273,13 @@ static int strntoll(const char *str, size_t sz, char **end, int base, for (; beg && sz && *beg == ' '; beg++, sz--) {}; - if (!sz) - return 1; - if (sz >= sizeof(buf)) - sz = sizeof(buf) -1; + if (!sz) return 1; + if (sz >= sizeof(buf)) sz = sizeof(buf) - 1; memcpy(buf, beg, sz); buf[sz] = '\0'; ret = strtoll(buf, end, base); - if ((ret == LLONG_MIN || ret == LLONG_MAX) && errno == ERANGE) - return 1; + if ((ret == LLONG_MIN || ret == LLONG_MAX) && errno == ERANGE) return 1; if (end) *end = (char *)beg + (*end - buf); *out = ret; @@ -291,7 +288,7 @@ static int strntoll(const char *str, size_t sz, char **end, int base, } static int strntoull(const char *str, size_t sz, char **end, int base, - unsigned long long* out) { + unsigned long long *out) { char buf[64]; unsigned long long ret; @@ -300,16 +297,13 @@ static int strntoull(const char *str, size_t sz, char **end, int base, for (; beg && sz && *beg == ' '; beg++, sz--) ; - if (!sz) - return 1; - if (sz >= sizeof(buf)) - sz = sizeof(buf) -1; + if (!sz) return 1; + if (sz >= sizeof(buf)) sz = sizeof(buf) - 1; memcpy(buf, beg, sz); buf[sz] = '\0'; ret = strtoull(buf, end, base); - if (ret == ULLONG_MAX && errno == ERANGE) - return 1; + if (ret == ULLONG_MAX && errno == ERANGE) return 1; if (end) *end = (char *)beg + (*end - buf); *out = ret; @@ -350,6 +344,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, use_unum = 1; } else + use_num = 1; } -- cgit v1.2.3 From e4a86b40a5504c608d6ba7f44133ab39b24ac6f8 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 1 Sep 2020 13:42:33 +0200 Subject: child cleanup --- src/afl-forkserver.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 93203cb2..cb4e00f9 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -240,6 +240,17 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) { if (!child_pid) { // New child + close(fsrv->out_dir_fd); + close(fsrv->dev_null_fd); + close(fsrv->dev_urandom_fd); + + if (fsrv->plot_file != NULL) { + + fclose(fsrv->plot_file); + fsrv->plot_file = NULL; + + } + signal(SIGCHLD, old_sigchld_handler); // FORKSRV_FD is for communication with AFL, we don't need it in the // child. @@ -360,12 +371,10 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (!fsrv->fsrv_pid) { /* CHILD PROCESS */ - struct rlimit r; /* Umpf. On OpenBSD, the default fd limit for root users is set to soft 128. Let's try to fix that... */ - if (!getrlimit(RLIMIT_NOFILE, &r) && r.rlim_cur < FORKSRV_FD + 2) { r.rlim_cur = FORKSRV_FD + 2; @@ -432,7 +441,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, close(fsrv->dev_null_fd); close(fsrv->dev_urandom_fd); - if (fsrv->plot_file != NULL) { fclose(fsrv->plot_file); } + if (fsrv->plot_file != NULL) { + + fclose(fsrv->plot_file); + fsrv->plot_file = NULL; + + } /* This should improve performance a bit, since it stops the linker from doing extra work post-fork(). */ -- cgit v1.2.3 From 08f6e1d66aef1d005e85d6a7871358230a52f65d Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 2 Sep 2020 17:54:54 +0200 Subject: children terminate on sigpipe --- src/afl-forkserver.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index cb4e00f9..58932bc4 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -251,6 +251,12 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) { } + // enable terminating on sigpipe in the childs + struct sigaction sa; + memset((char *)&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_DFL; + sigaction(SIGPIPE, &sa, NULL); + signal(SIGCHLD, old_sigchld_handler); // FORKSRV_FD is for communication with AFL, we don't need it in the // child. @@ -371,6 +377,13 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (!fsrv->fsrv_pid) { /* CHILD PROCESS */ + + // enable terminating on sigpipe in the childs + struct sigaction sa; + memset((char *)&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_DFL; + sigaction(SIGPIPE, &sa, NULL); + struct rlimit r; /* Umpf. On OpenBSD, the default fd limit for root users is set to -- cgit v1.2.3 From c39a552cc0e2beea85b519e682771e0325354bda Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 2 Sep 2020 20:30:26 +0200 Subject: ignore unstable --- src/afl-fuzz-run.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index d71ec339..ee22b0f6 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -394,6 +394,8 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, unlikely(afl->first_trace[i] != afl->fsrv.trace_bits[i])) { afl->var_bytes[i] = 1; + // ignore the variable edge by setting it to fully discovered + afl->virgin_bits[i] = 0; } -- cgit v1.2.3 From 4c48d3a3ad1c0c8199b40ef47517b8a736cd5579 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 3 Sep 2020 09:59:23 +0200 Subject: update xxh3 to 0.8.0, fix is_ascii --- src/afl-fuzz-queue.c | 6 +++--- src/afl-performance.c | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 0c472845..c6d8225f 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -138,9 +138,9 @@ static u8 check_if_text(struct queue_entry *q) { } // non-overlong 2-byte - if (((0xC2 <= buf[offset + 0] && buf[offset + 0] <= 0xDF) && - (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF)) && - len - offset > 1) { + if (len - offset > 1 && + ((0xC2 <= buf[offset + 0] && buf[offset + 0] <= 0xDF) && + (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF))) { offset += 2; utf8++; diff --git a/src/afl-performance.c b/src/afl-performance.c index a9d7cefa..7a80ac4b 100644 --- a/src/afl-performance.c +++ b/src/afl-performance.c @@ -22,7 +22,10 @@ #include #include "afl-fuzz.h" #include "types.h" -#include "xxh3.h" + +#define XXH_INLINE_ALL +#include "xxhash.h" +#undef XXH_INLINE_ALL /* we use xoshiro256** instead of rand/random because it is 10x faster and has better randomness properties. */ -- cgit v1.2.3 From e45ae8e5da9d603976a4fde1184455e5e9c49051 Mon Sep 17 00:00:00 2001 From: Thomas Rooijakkers Date: Fri, 4 Sep 2020 13:13:47 +0200 Subject: Export set afl_environment_variables to stats --- src/afl-fuzz-stats.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 0ce35cb7..38c954e5 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -24,6 +24,7 @@ */ #include "afl-fuzz.h" +#include "envs.h" #include /* Update stats file for unattended monitoring. */ @@ -163,11 +164,28 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, ? "" : "default", afl->orig_cmdline); + + char * val; + uint32_t i = 0; + uint32_t s_afl_env = + sizeof(afl_environment_variables) / sizeof(afl_environment_variables[0]) - + 1; + + for (i = 0; i < s_afl_env; i++) { + + if ((val = get_afl_env(afl_environment_variables[i])) != NULL) { + + fprintf(f, "%-18.*s: %s\n", strlen(afl_environment_variables[i]), + afl_environment_variables[i], val); + + } + + } + /* ignore errors */ if (afl->debug) { - uint32_t i = 0; fprintf(f, "virgin_bytes :"); for (i = 0; i < afl->fsrv.map_size; i++) { -- cgit v1.2.3 From 6adaacbb3aed2f967b4f3aeacdc41e91502914b3 Mon Sep 17 00:00:00 2001 From: Thomas Rooijakkers Date: Fri, 4 Sep 2020 15:46:46 +0200 Subject: Seperate fuzzer_setup from fuzzer_stats, only write fuzzer_setup at the start --- src/afl-fuzz-stats.c | 93 +++++++++++++++++++++++++++++++++++++--------------- src/afl-fuzz.c | 1 + 2 files changed, 67 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 38c954e5..45b1326c 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -27,6 +27,69 @@ #include "envs.h" #include +/* Open file for writing */ + +FILE *open_file(const char *fn) { + + s32 fd; + FILE *f; + + fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600); + + if (fd < 0) { PFATAL("Unable to create '%s'", fn); } + + f = fdopen(fd, "w"); + + if (!f) { PFATAL("fdopen() failed"); } + + return f; + +} + +/* Write fuzzer setup file */ + +void write_fuzzer_setup_file(afl_state_t *afl) { + + u8 fn[PATH_MAX]; + FILE *f; + + snprintf(fn, PATH_MAX, "%s/fuzzer_setup", afl->out_dir); + f = open_file(fn); + + char * val; + uint32_t i = 0; + uint32_t s_afl_env = + sizeof(afl_environment_variables) / sizeof(afl_environment_variables[0]) - + 1; + + uint32_t max_len = 0; + uint32_t cur_len = 0; + for (i = 0; i < s_afl_env; i++) { + + if ((val = getenv(afl_environment_variables[i])) != NULL) { + + cur_len = strlen(afl_environment_variables[i]); + max_len = cur_len > max_len ? cur_len : max_len; + + } + + } + + for (i = 0; i < s_afl_env; i++) { + + if ((val = getenv(afl_environment_variables[i])) != NULL) { + + fprintf(f, "%*.*s : %s\n", -max_len, strlen(afl_environment_variables[i]), + afl_environment_variables[i], val); + + } + + } + + fclose(f); + +} + /* Update stats file for unattended monitoring. */ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, @@ -37,20 +100,12 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, #endif unsigned long long int cur_time = get_cur_time(); + u32 t_bytes = count_non_255_bytes(afl, afl->virgin_bits); u8 fn[PATH_MAX]; - s32 fd; FILE * f; - u32 t_bytes = count_non_255_bytes(afl, afl->virgin_bits); snprintf(fn, PATH_MAX, "%s/fuzzer_stats", afl->out_dir); - - fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600); - - if (fd < 0) { PFATAL("Unable to create '%s'", fn); } - - f = fdopen(fd, "w"); - - if (!f) { PFATAL("fdopen() failed"); } + f = open_file(fn); /* Keep last values in case we're called from another context where exec/sec stats and such are not readily available. */ @@ -165,27 +220,11 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, : "default", afl->orig_cmdline); - char * val; - uint32_t i = 0; - uint32_t s_afl_env = - sizeof(afl_environment_variables) / sizeof(afl_environment_variables[0]) - - 1; - - for (i = 0; i < s_afl_env; i++) { - - if ((val = get_afl_env(afl_environment_variables[i])) != NULL) { - - fprintf(f, "%-18.*s: %s\n", strlen(afl_environment_variables[i]), - afl_environment_variables[i], val); - - } - - } - /* ignore errors */ if (afl->debug) { + uint32_t i = 0; fprintf(f, "virgin_bytes :"); for (i = 0; i < afl->fsrv.map_size; i++) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 0df6c15c..ae060b07 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1274,6 +1274,7 @@ int main(int argc, char **argv_orig, char **envp) { seek_to = find_start_position(afl); + write_fuzzer_setup_file(afl); write_stats_file(afl, 0, 0, 0); maybe_update_plot_file(afl, 0, 0); save_auto(afl); -- cgit v1.2.3 From 809a7cffe2de74b048143f0820fa922c9a18aff5 Mon Sep 17 00:00:00 2001 From: Thomas Rooijakkers Date: Fri, 4 Sep 2020 16:02:09 +0200 Subject: Write set environment variables in an env file style. --- src/afl-fuzz-stats.c | 27 ++++++--------------------- src/afl-fuzz.c | 2 +- 2 files changed, 7 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 45b1326c..298ad229 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -48,39 +48,24 @@ FILE *open_file(const char *fn) { /* Write fuzzer setup file */ -void write_fuzzer_setup_file(afl_state_t *afl) { +void write_fuzzer_config_file(afl_state_t *afl) { u8 fn[PATH_MAX]; FILE *f; - snprintf(fn, PATH_MAX, "%s/fuzzer_setup", afl->out_dir); + snprintf(fn, PATH_MAX, "%s/fuzzer_config", afl->out_dir); f = open_file(fn); - char * val; - uint32_t i = 0; + char *val; + uint32_t s_afl_env = sizeof(afl_environment_variables) / sizeof(afl_environment_variables[0]) - 1; - - uint32_t max_len = 0; - uint32_t cur_len = 0; - for (i = 0; i < s_afl_env; i++) { - - if ((val = getenv(afl_environment_variables[i])) != NULL) { - - cur_len = strlen(afl_environment_variables[i]); - max_len = cur_len > max_len ? cur_len : max_len; - - } - - } - - for (i = 0; i < s_afl_env; i++) { + for (uint32_t i = 0; i < s_afl_env; i++) { if ((val = getenv(afl_environment_variables[i])) != NULL) { - fprintf(f, "%*.*s : %s\n", -max_len, strlen(afl_environment_variables[i]), - afl_environment_variables[i], val); + fprintf(f, "%s=%s\n", afl_environment_variables[i], val); } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index ae060b07..e9ea8b62 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1274,7 +1274,7 @@ int main(int argc, char **argv_orig, char **envp) { seek_to = find_start_position(afl); - write_fuzzer_setup_file(afl); + write_fuzzer_config_file(afl); write_stats_file(afl, 0, 0, 0); maybe_update_plot_file(afl, 0, 0); save_auto(afl); -- cgit v1.2.3 From 50f61b64b1bbf2f5354bcff4f1d225965fee2d06 Mon Sep 17 00:00:00 2001 From: Thomas Rooijakkers Date: Fri, 4 Sep 2020 16:22:22 +0200 Subject: Make open_file() inline --- src/afl-fuzz-stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 298ad229..b59a40e4 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -29,7 +29,7 @@ /* Open file for writing */ -FILE *open_file(const char *fn) { +inline FILE *open_file(const char *fn) { s32 fd; FILE *f; -- cgit v1.2.3 From 6c715f1a69f91d4336023a8ba10fb4a7e126f9c2 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 4 Sep 2020 17:04:42 +0200 Subject: more changes to fuzzer_setup --- src/afl-common.c | 33 +++++++++++++++++++++++++ src/afl-fuzz-stats.c | 70 ++++++++++++++++++++++++++++------------------------ src/afl-fuzz.c | 3 ++- 3 files changed, 73 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 367dec72..d66440aa 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -877,3 +877,36 @@ u32 get_map_size(void) { } +/* Create a stream file */ + +FILE *create_ffile(u8 *fn) { + + s32 fd; + FILE *f; + + fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600); + + if (fd < 0) { PFATAL("Unable to create '%s'", fn); } + + f = fdopen(fd, "w"); + + if (!f) { PFATAL("fdopen() failed"); } + + return f; + +} + +/* Create a file */ + +s32 create_file(u8 *fn) { + + s32 fd; + + fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600); + + if (fd < 0) { PFATAL("Unable to create '%s'", fn); } + + return fd; + +} + diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index b59a40e4..a84f1c7a 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -27,51 +27,57 @@ #include "envs.h" #include -/* Open file for writing */ - -inline FILE *open_file(const char *fn) { - - s32 fd; - FILE *f; - - fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600); +/* Write fuzzer setup file */ - if (fd < 0) { PFATAL("Unable to create '%s'", fn); } +void write_setup_file(afl_state_t *afl, int argc, char **argv) { - f = fdopen(fd, "w"); + char *val; + u8 fn[PATH_MAX]; + snprintf(fn, PATH_MAX, "%s/fuzzer_setup", afl->out_dir); + FILE *f = create_ffile(fn); - if (!f) { PFATAL("fdopen() failed"); } + fprintf(f, "# environment variables:\n"); + u32 s_afl_env = + sizeof(afl_environment_variables) / sizeof(afl_environment_variables[0]) - + 1; + for (u32 i = 0; i < s_afl_env; i++) { - return f; + if ((val = getenv(afl_environment_variables[i])) != NULL) { -} + fprintf(f, "%s=%s\n", afl_environment_variables[i], val); -/* Write fuzzer setup file */ + } -void write_fuzzer_config_file(afl_state_t *afl) { + } - u8 fn[PATH_MAX]; - FILE *f; + fprintf(f, "# command line:\n"); - snprintf(fn, PATH_MAX, "%s/fuzzer_config", afl->out_dir); - f = open_file(fn); + s32 i; + size_t j; + for (i = 0; i < argc; i++) { - char *val; + if (i) fprintf(f, " "); + if (index(argv[i], '\'')) { - uint32_t s_afl_env = - sizeof(afl_environment_variables) / sizeof(afl_environment_variables[0]) - - 1; - for (uint32_t i = 0; i < s_afl_env; i++) { + fprintf(f, "'"); + for (j = 0; j < strlen(argv[i]); j++) + if (argv[i][j] == '\'') + fprintf(f, "'\"'\"'"); + else + fprintf(f, "%c", argv[i][j]); + fprintf(f, "'"); - if ((val = getenv(afl_environment_variables[i])) != NULL) { + } else { - fprintf(f, "%s=%s\n", afl_environment_variables[i], val); + fprintf(f, "'%s'", argv[i]); } } + fprintf(f, "\n"); fclose(f); + (void)(afl_environment_deprecated); } @@ -84,13 +90,13 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, struct rusage rus; #endif - unsigned long long int cur_time = get_cur_time(); - u32 t_bytes = count_non_255_bytes(afl, afl->virgin_bits); - u8 fn[PATH_MAX]; - FILE * f; + u64 cur_time = get_cur_time(); + u32 t_bytes = count_non_255_bytes(afl, afl->virgin_bits); + u8 fn[PATH_MAX]; + FILE *f; snprintf(fn, PATH_MAX, "%s/fuzzer_stats", afl->out_dir); - f = open_file(fn); + f = create_ffile(fn); /* Keep last values in case we're called from another context where exec/sec stats and such are not readily available. */ @@ -209,7 +215,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, if (afl->debug) { - uint32_t i = 0; + u32 i = 0; fprintf(f, "virgin_bytes :"); for (i = 0; i < afl->fsrv.map_size; i++) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e9ea8b62..c12d5db5 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1128,6 +1128,8 @@ int main(int argc, char **argv_orig, char **envp) { setup_custom_mutators(afl); + write_setup_file(afl, argc, argv); + setup_cmdline_file(afl, argv + optind); read_testcases(afl); @@ -1274,7 +1276,6 @@ int main(int argc, char **argv_orig, char **envp) { seek_to = find_start_position(afl); - write_fuzzer_config_file(afl); write_stats_file(afl, 0, 0, 0); maybe_update_plot_file(afl, 0, 0); save_auto(afl); -- cgit v1.2.3 From b7b38205d816e20a5e3c87adcdd1fdb6de612755 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 4 Sep 2020 17:37:11 +0200 Subject: fix travis --- src/afl-fuzz-stats.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index a84f1c7a..7e77532e 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -35,12 +35,14 @@ void write_setup_file(afl_state_t *afl, int argc, char **argv) { u8 fn[PATH_MAX]; snprintf(fn, PATH_MAX, "%s/fuzzer_setup", afl->out_dir); FILE *f = create_ffile(fn); + u32 i; fprintf(f, "# environment variables:\n"); u32 s_afl_env = sizeof(afl_environment_variables) / sizeof(afl_environment_variables[0]) - 1; - for (u32 i = 0; i < s_afl_env; i++) { + + for (i = 0; i < s_afl_env; i++) { if ((val = getenv(afl_environment_variables[i])) != NULL) { -- cgit v1.2.3 From 77b824d1014c3fb11804a2e91d28d155cd0f62d1 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 4 Sep 2020 17:56:17 +0200 Subject: compile fix --- src/afl-fuzz-stats.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 7e77532e..05cbafef 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -35,10 +35,10 @@ void write_setup_file(afl_state_t *afl, int argc, char **argv) { u8 fn[PATH_MAX]; snprintf(fn, PATH_MAX, "%s/fuzzer_setup", afl->out_dir); FILE *f = create_ffile(fn); - u32 i; + s32 i; fprintf(f, "# environment variables:\n"); - u32 s_afl_env = + s32 s_afl_env = (s32) sizeof(afl_environment_variables) / sizeof(afl_environment_variables[0]) - 1; @@ -54,7 +54,6 @@ void write_setup_file(afl_state_t *afl, int argc, char **argv) { fprintf(f, "# command line:\n"); - s32 i; size_t j; for (i = 0; i < argc; i++) { -- cgit v1.2.3 From 0625eb0a051247c7b39df987289ad9a0e089a181 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Fri, 4 Sep 2020 22:26:39 +0200 Subject: avoid signed ints for amounts (which are positive) --- src/afl-fuzz-stats.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 05cbafef..07d83f07 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -29,20 +29,20 @@ /* Write fuzzer setup file */ -void write_setup_file(afl_state_t *afl, int argc, char **argv) { +void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { char *val; u8 fn[PATH_MAX]; snprintf(fn, PATH_MAX, "%s/fuzzer_setup", afl->out_dir); FILE *f = create_ffile(fn); - s32 i; + u32 i; fprintf(f, "# environment variables:\n"); - s32 s_afl_env = (s32) + u32 s_afl_env = sizeof(afl_environment_variables) / sizeof(afl_environment_variables[0]) - - 1; + 1U; - for (i = 0; i < s_afl_env; i++) { + for (i = 0; i < s_afl_env; ++i) { if ((val = getenv(afl_environment_variables[i])) != NULL) { @@ -55,7 +55,7 @@ void write_setup_file(afl_state_t *afl, int argc, char **argv) { fprintf(f, "# command line:\n"); size_t j; - for (i = 0; i < argc; i++) { + for (i = 0; i < argc; ++i) { if (i) fprintf(f, " "); if (index(argv[i], '\'')) { -- cgit v1.2.3 From 976ee9022cda95e0715b82ff866098ad293117c9 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 4 Sep 2020 22:47:37 +0200 Subject: fix assignment --- src/afl-fuzz-stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 07d83f07..51eed14b 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -38,7 +38,7 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { u32 i; fprintf(f, "# environment variables:\n"); - u32 s_afl_env = + u32 s_afl_env = (u32) sizeof(afl_environment_variables) / sizeof(afl_environment_variables[0]) - 1U; -- cgit v1.2.3 From 996986bed5f2dd97a3d76f584d8eddc1203f8396 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 5 Sep 2020 12:11:48 +0200 Subject: first batch of changes --- src/afl-cc.c | 1544 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/afl-gcc.c | 488 ----------------- src/afl-ld-lto.c | 358 +++++++++++++ 3 files changed, 1902 insertions(+), 488 deletions(-) create mode 100644 src/afl-cc.c delete mode 100644 src/afl-gcc.c create mode 100644 src/afl-ld-lto.c (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c new file mode 100644 index 00000000..e11ce40a --- /dev/null +++ b/src/afl-cc.c @@ -0,0 +1,1544 @@ +/* + american fuzzy lop++ - compiler instrumentation wrapper + ------------------------------------------------------- + + Written by Michal Zalewski, Laszlo Szekeres and Marc Heuse + + Copyright 2015, 2016 Google Inc. All rights reserved. + Copyright 2019-2020 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. + You may obtain a copy of the License at: + + http://www.apache.org/licenses/LICENSE-2.0 + + */ + +#define AFL_MAIN + +#include "common.h" +#include "config.h" +#include "types.h" +#include "debug.h" +#include "alloc-inl.h" +#include "llvm-ngram-coverage.h" + +#include +#include +#include +#include +#include +#include +#include + +#if (LLVM_MAJOR - 0 == 0) + #undef LLVM_MAJOR +#endif +#if !defined(LLVM_MAJOR) + #define LLVM_MAJOR 0 +#endif + +static u8 * obj_path; /* Path to runtime libraries */ +static u8 **cc_params; /* Parameters passed to the real CC */ +static u32 cc_par_cnt = 1; /* Param count, including argv0 */ +static u8 llvm_fullpath[PATH_MAX]; +static u8 instrument_mode, instrument_opt_mode, ngram_size, lto_mode, + compiler_mode, plusplus_mode; +static u8 have_gcc, have_llvm, have_gcc_plugin, have_lto; +static u8 *lto_flag = AFL_CLANG_FLTO, *argvnull; +static u8 debug; +static u8 cwd[4096]; +static u8 cmplog_mode; +u8 use_stdin; /* dummy */ +// static u8 *march_opt = CFLAGS_OPT; + +enum { + + INSTURMENT_DEFAULT = 0, + INSTRUMENT_CLASSIC = 1, + INSTRUMENT_AFL = 1, + INSTRUMENT_PCGUARD = 2, + INSTRUMENT_INSTRIM = 3, + INSTRUMENT_CFG = 3, + INSTRUMENT_LTO = 4, + INSTRUMENT_OPT_CTX = 8, + INSTRUMENT_OPT_NGRAM = 16 + +}; + +char instrument_mode_string[18][18] = { + + "DEFAULT", "CLASSIC", "PCGUARD", "CFG", "LTO", "", "", "", "CTX", "", + "", "", "", "", "", "", "NGRAM", "" + +}; + +enum { + + UNSET = 0, + LTO = 1, + LLVM = 2, + GCC_PLUGIN = 3, + GCC = 4 + +}; + +char compiler_mode_string[6][12] = { + + "AUTOSELECT", "LLVM-LTO", "LLVM", "GCC_PLUGIN", + "GCC", "" + +}; + +u8 *getthecwd() { + + static u8 fail[] = ""; + if (getcwd(cwd, sizeof(cwd)) == NULL) return fail; + return cwd; + +} + +/* Try to find the runtime libraries. If that fails, abort. */ + +static u8 *find_object(u8 *obj, u8 *argv0) { + + u8 *afl_path = getenv("AFL_PATH"); + u8 *slash = NULL, *tmp; + + if (afl_path) { + +#ifdef __ANDROID__ + tmp = alloc_printf("%s/%s", afl_path, obj); +#else + tmp = alloc_printf("%s/%s", afl_path, obj); +#endif + + if (!access(tmp, R_OK)) { + + obj_path = afl_path; + return tmp; + + } + + ck_free(tmp); + + } + + if (argv0) slash = strrchr(argv0, '/'); + + if (slash) { + + u8 *dir; + + *slash = 0; + dir = ck_strdup(argv0); + *slash = '/'; + +#ifdef __ANDROID__ + tmp = alloc_printf("%s/%s", dir, obj); +#else + tmp = alloc_printf("%s/%s", dir, obj); +#endif + + if (!access(tmp, R_OK)) { + + obj_path = dir; + return tmp; + + } + + ck_free(tmp); + ck_free(dir); + + } + + tmp = alloc_printf("%s/%s", AFL_PATH, obj); +#ifdef __ANDROID__ + if (!access(tmp, R_OK)) { + +#else + if (!access(tmp, R_OK)) { + +#endif + + obj_path = AFL_PATH; + return tmp; + + } + + ck_free(tmp); + return NULL; + +} + +/* Try to find the runtime libraries. If that fails, abort. */ + +static void find_obj(u8 *argv0) { + + u8 *afl_path = getenv("AFL_PATH"); + u8 *slash, *tmp; + + if (afl_path) { + +#ifdef __ANDROID__ + tmp = alloc_printf("%s/afl-compiler-rt.so", afl_path); +#else + tmp = alloc_printf("%s/afl-compiler-rt.o", afl_path); +#endif + + if (!access(tmp, R_OK)) { + + obj_path = afl_path; + ck_free(tmp); + return; + + } + + ck_free(tmp); + + } + + slash = strrchr(argv0, '/'); + + if (slash) { + + u8 *dir; + + *slash = 0; + dir = ck_strdup(argv0); + *slash = '/'; + +#ifdef __ANDROID__ + tmp = alloc_printf("%s/afl-compiler-rt.so", dir); +#else + tmp = alloc_printf("%s/afl-compiler-rt.o", dir); +#endif + + if (!access(tmp, R_OK)) { + + obj_path = dir; + ck_free(tmp); + return; + + } + + ck_free(tmp); + ck_free(dir); + + } + +#ifdef __ANDROID__ + if (!access(AFL_PATH "/afl-compiler-rt.so", R_OK)) { + +#else + if (!access(AFL_PATH "/afl-compiler-rt.o", R_OK)) { + +#endif + + obj_path = AFL_PATH; + return; + + } + + FATAL( + "Unable to find 'afl-compiler-rt.o' or 'afl-llvm-pass.so'. Please set " + "AFL_PATH"); + +} + +/* Copy argv to cc_params, making the necessary edits. */ + +static void edit_params(u32 argc, char **argv, char **envp) { + + u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0, shared_linking = 0, + preprocessor_only = 0, have_unroll = 0, have_o = 0, have_pic = 0; + u8 *name; + + cc_params = ck_alloc((argc + 128) * sizeof(u8 *)); + + name = strrchr(argv[0], '/'); + if (!name) + name = argv[0]; + else + ++name; + + if (lto_mode) { + + if (lto_flag[0] != '-') + FATAL( + "Using afl-clang-lto is not possible because Makefile magic did not " + "identify the correct -flto flag"); + else + compiler_mode = LTO; + + } + + if (plusplus_mode) { + + u8 *alt_cxx = getenv("AFL_CXX"); + + if (!alt_cxx) { + + if (compiler_mode >= GCC_PLUGIN) { + + alt_cxx = "g++"; + + } else { + + if (USE_BINDIR) + snprintf(llvm_fullpath, sizeof(llvm_fullpath), "%s/clang++", + LLVM_BINDIR); + else + snprintf(llvm_fullpath, sizeof(llvm_fullpath), CLANGPP_BIN); + alt_cxx = llvm_fullpath; + + } + + } + + cc_params[0] = alt_cxx; + + } else { + + u8 *alt_cc = getenv("AFL_CC"); + + if (!alt_cc) { + + if (compiler_mode >= GCC_PLUGIN) { + + alt_cc = "gcc"; + + } else { + + if (USE_BINDIR) + snprintf(llvm_fullpath, sizeof(llvm_fullpath), "%s/clang", + LLVM_BINDIR); + else + snprintf(llvm_fullpath, sizeof(llvm_fullpath), CLANGPP_BIN); + alt_cc = llvm_fullpath; + + } + + } + + cc_params[0] = alt_cc; + + } + + if (compiler_mode == GCC) { + + cc_params[cc_par_cnt++] = "-B"; + cc_params[cc_par_cnt++] = obj_path; + + } + + if (compiler_mode == GCC_PLUGIN) { + + char *fplugin_arg = + alloc_printf("-fplugin=%s", find_object("afl-gcc-pass.so", argvnull)); + cc_params[cc_par_cnt++] = fplugin_arg; + + } + + if (compiler_mode == LLVM || compiler_mode == LTO) { + + cc_params[cc_par_cnt++] = "-Wno-unused-command-line-argument"; + + if (lto_mode && plusplus_mode) + cc_params[cc_par_cnt++] = "-lc++"; // needed by fuzzbench, early + + if (lto_mode) { + + if (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || + getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") || + getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) { + + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-lto-instrumentlist.so", obj_path); + + } + + } + + if (getenv("AFL_LLVM_DICT2FILE")) { + + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-dict2file.so", obj_path); + + } + + // laf + if (getenv("LAF_SPLIT_SWITCHES") || getenv("AFL_LLVM_LAF_SPLIT_SWITCHES")) { + + if (lto_mode) { + + cc_params[cc_par_cnt++] = alloc_printf( + "-Wl,-mllvm=-load=%s/split-switches-pass.so", obj_path); + + } else { + + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/split-switches-pass.so", obj_path); + + } + + } + + if (getenv("LAF_TRANSFORM_COMPARES") || + getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")) { + + if (lto_mode) { + + cc_params[cc_par_cnt++] = alloc_printf( + "-Wl,-mllvm=-load=%s/compare-transform-pass.so", obj_path); + + } else { + + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/compare-transform-pass.so", obj_path); + + } + + } + + if (getenv("LAF_SPLIT_COMPARES") || getenv("AFL_LLVM_LAF_SPLIT_COMPARES") || + getenv("AFL_LLVM_LAF_SPLIT_FLOATS")) { + + if (lto_mode) { + + cc_params[cc_par_cnt++] = alloc_printf( + "-Wl,-mllvm=-load=%s/split-compares-pass.so", obj_path); + + } else { + + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/split-compares-pass.so", obj_path); + + } + + } + + // /laf + + unsetenv("AFL_LD"); + unsetenv("AFL_LD_CALLER"); + if (cmplog_mode) { + + if (lto_mode) { + + cc_params[cc_par_cnt++] = alloc_printf( + "-Wl,-mllvm=-load=%s/cmplog-routines-pass.so", obj_path); + cc_params[cc_par_cnt++] = alloc_printf( + "-Wl,-mllvm=-load=%s/split-switches-pass.so", obj_path); + cc_params[cc_par_cnt++] = alloc_printf( + "-Wl,-mllvm=-load=%s/cmplog-instructions-pass.so", obj_path); + + } else { + + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/cmplog-routines-pass.so", obj_path); + + // reuse split switches from laf + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/split-switches-pass.so", obj_path); + + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/cmplog-instructions-pass.so", obj_path); + + } + + cc_params[cc_par_cnt++] = "-fno-inline"; + + } + + if (lto_mode) { + + u8 *ld_path = strdup(AFL_REAL_LD); + if (!*ld_path) ld_path = "ld.lld"; +#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 12 + cc_params[cc_par_cnt++] = alloc_printf("--ld-path=%s", ld_path); +#else + cc_params[cc_par_cnt++] = alloc_printf("-fuse-ld=%s", ld_path); +#endif + + cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition"; + + if (instrument_mode == INSTRUMENT_CFG) + cc_params[cc_par_cnt++] = alloc_printf( + "-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path); + else + + cc_params[cc_par_cnt++] = alloc_printf( + "-Wl,-mllvm=-load=%s/afl-llvm-lto-instrumentation.so", obj_path); + cc_params[cc_par_cnt++] = lto_flag; + + } else { + + if (instrument_mode == INSTRUMENT_PCGUARD) { + +#if LLVM_MAJOR >= 4 + cc_params[cc_par_cnt++] = + "-fsanitize-coverage=trace-pc-guard"; // edge coverage by default +#else + FATAL("pcguard instrumentation requires llvm 4.0.1+"); +#endif + + } else { + + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + if (instrument_mode == INSTRUMENT_CFG) + cc_params[cc_par_cnt++] = + alloc_printf("%s/libLLVMInsTrim.so", obj_path); + else + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-pass.so", obj_path); + + } + + } + + // cc_params[cc_par_cnt++] = "-Qunused-arguments"; + + // in case LLVM is installed not via a package manager or "make install" + // e.g. compiled download or compiled from github then its ./lib directory + // might not be in the search path. Add it if so. + u8 *libdir = strdup(LLVM_LIBDIR); + if (plusplus_mode && strlen(libdir) && strncmp(libdir, "/usr", 4) && + strncmp(libdir, "/lib", 4)) { + + cc_params[cc_par_cnt++] = "-rpath"; + cc_params[cc_par_cnt++] = libdir; + + } else { + + free(libdir); + + } + + u32 idx; + if (lto_mode && argc > 1) { + + for (idx = 1; idx < argc; idx++) { + + if (!strncasecmp(argv[idx], "-fpic", 5)) have_pic = 1; + + } + + if (!have_pic) cc_params[cc_par_cnt++] = "-fPIC"; + + } + + } + + /* Detect stray -v calls from ./configure scripts. */ + + while (--argc) { + + u8 *cur = *(++argv); + + if (!strncmp(cur, "--afl", 5)) continue; + if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue; + if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue; + if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined")) + continue; + + if (!strcmp(cur, "-m32")) bit_mode = 32; + if (!strcmp(cur, "armv7a-linux-androideabi")) bit_mode = 32; + if (!strcmp(cur, "-m64")) bit_mode = 64; + + if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory")) + asan_set = 1; + + if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1; + + if (!strcmp(cur, "-x")) x_set = 1; + if (!strcmp(cur, "-E")) preprocessor_only = 1; + if (!strcmp(cur, "-shared")) shared_linking = 1; + + if (!strncmp(cur, "-O", 2)) have_o = 1; + if (!strncmp(cur, "-f", 2) && strstr(cur, "unroll-loop")) have_unroll = 1; + + cc_params[cc_par_cnt++] = cur; + + } + + if (getenv("AFL_HARDEN")) { + + cc_params[cc_par_cnt++] = "-fstack-protector-all"; + + if (!fortify_set) cc_params[cc_par_cnt++] = "-D_FORTIFY_SOURCE=2"; + + } + + if (!asan_set) { + + if (getenv("AFL_USE_ASAN")) { + + if (getenv("AFL_USE_MSAN")) FATAL("ASAN and MSAN are mutually exclusive"); + + if (getenv("AFL_HARDEN")) + FATAL("ASAN and AFL_HARDEN are mutually exclusive"); + + cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE"; + cc_params[cc_par_cnt++] = "-fsanitize=address"; + + } else if (getenv("AFL_USE_MSAN")) { + + if (getenv("AFL_USE_ASAN")) FATAL("ASAN and MSAN are mutually exclusive"); + + if (getenv("AFL_HARDEN")) + FATAL("MSAN and AFL_HARDEN are mutually exclusive"); + + cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE"; + cc_params[cc_par_cnt++] = "-fsanitize=memory"; + + } + + } + + if (getenv("AFL_USE_UBSAN")) { + + cc_params[cc_par_cnt++] = "-fsanitize=undefined"; + cc_params[cc_par_cnt++] = "-fsanitize-undefined-trap-on-error"; + cc_params[cc_par_cnt++] = "-fno-sanitize-recover=all"; + + } + + if (getenv("AFL_USE_CFISAN")) { + + if (!lto_mode) { + + uint32_t i = 0, found = 0; + while (envp[i] != NULL && !found) + if (strncmp("-flto", envp[i++], 5) == 0) found = 1; + if (!found) cc_params[cc_par_cnt++] = "-flto"; + + } + + cc_params[cc_par_cnt++] = "-fsanitize=cfi"; + cc_params[cc_par_cnt++] = "-fvisibility=hidden"; + + } + + if (!getenv("AFL_DONT_OPTIMIZE")) { + + cc_params[cc_par_cnt++] = "-g"; + if (!have_o) cc_params[cc_par_cnt++] = "-O3"; + if (!have_unroll) cc_params[cc_par_cnt++] = "-funroll-loops"; + // if (strlen(march_opt) > 1 && march_opt[0] == '-') + // cc_params[cc_par_cnt++] = march_opt; + + } + + if (getenv("AFL_NO_BUILTIN") || getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES") || + getenv("LAF_TRANSFORM_COMPARES") || lto_mode) { + + cc_params[cc_par_cnt++] = "-fno-builtin-strcmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-strncmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-strcasecmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-memcmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-bcmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-strstr"; + cc_params[cc_par_cnt++] = "-fno-builtin-strcasestr"; + + } + +#if defined(USEMMAP) && !defined(__HAIKU__) + cc_params[cc_par_cnt++] = "-lrt"; +#endif + + cc_params[cc_par_cnt++] = "-D__AFL_HAVE_MANUAL_CONTROL=1"; + cc_params[cc_par_cnt++] = "-D__AFL_COMPILER=1"; + cc_params[cc_par_cnt++] = "-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1"; + + /* When the user tries to use persistent or deferred forkserver modes by + appending a single line to the program, we want to reliably inject a + signature into the binary (to be picked up by afl-fuzz) and we want + to call a function from the runtime .o file. This is unnecessarily + painful for three reasons: + + 1) We need to convince the compiler not to optimize out the signature. + This is done with __attribute__((used)). + + 2) We need to convince the linker, when called with -Wl,--gc-sections, + not to do the same. This is done by forcing an assignment to a + 'volatile' pointer. + + 3) We need to declare __afl_persistent_loop() in the global namespace, + but doing this within a method in a class is hard - :: and extern "C" + are forbidden and __attribute__((alias(...))) doesn't work. Hence the + __asm__ aliasing trick. + + */ + + cc_params[cc_par_cnt++] = + "-D__AFL_FUZZ_INIT()=" + "int __afl_sharedmem_fuzzing = 1;" + "extern unsigned int *__afl_fuzz_len;" + "extern unsigned char *__afl_fuzz_ptr;" + "unsigned char __afl_fuzz_alt[1024000];" + "unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt;"; + cc_params[cc_par_cnt++] = + "-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : " + "__afl_fuzz_alt_ptr)"; + cc_params[cc_par_cnt++] = + "-D__AFL_FUZZ_TESTCASE_LEN=(__afl_fuzz_ptr ? *__afl_fuzz_len : " + "(*__afl_fuzz_len = read(0, __afl_fuzz_alt_ptr, 1024000)) == 0xffffffff " + "? 0 : *__afl_fuzz_len)"; + + cc_params[cc_par_cnt++] = + "-D__AFL_LOOP(_A)=" + "({ static volatile char *_B __attribute__((used)); " + " _B = (char*)\"" PERSIST_SIG + "\"; " +#ifdef __APPLE__ + "__attribute__((visibility(\"default\"))) " + "int _L(unsigned int) __asm__(\"___afl_persistent_loop\"); " +#else + "__attribute__((visibility(\"default\"))) " + "int _L(unsigned int) __asm__(\"__afl_persistent_loop\"); " +#endif /* ^__APPLE__ */ + "_L(_A); })"; + + cc_params[cc_par_cnt++] = + "-D__AFL_INIT()=" + "do { static volatile char *_A __attribute__((used)); " + " _A = (char*)\"" DEFER_SIG + "\"; " +#ifdef __APPLE__ + "__attribute__((visibility(\"default\"))) " + "void _I(void) __asm__(\"___afl_manual_init\"); " +#else + "__attribute__((visibility(\"default\"))) " + "void _I(void) __asm__(\"__afl_manual_init\"); " +#endif /* ^__APPLE__ */ + "_I(); } while (0)"; + + if (x_set) { + + cc_params[cc_par_cnt++] = "-x"; + cc_params[cc_par_cnt++] = "none"; + + } + + if (preprocessor_only) { + + /* In the preprocessor_only case (-E), we are not actually compiling at + all but requesting the compiler to output preprocessed sources only. + We must not add the runtime in this case because the compiler will + simply output its binary content back on stdout, breaking any build + systems that rely on a separate source preprocessing step. */ + cc_params[cc_par_cnt] = NULL; + return; + + } + +#ifndef __ANDROID__ + + if (compiler_mode != GCC) { + + switch (bit_mode) { + + case 0: + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-compiler-rt.o", obj_path); + if (lto_mode) + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-rt-lto.o", obj_path); + break; + + case 32: + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-compiler-rt-32.o", obj_path); + if (access(cc_params[cc_par_cnt - 1], R_OK)) + FATAL("-m32 is not supported by your compiler"); + if (lto_mode) { + + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-rt-lto-32.o", obj_path); + if (access(cc_params[cc_par_cnt - 1], R_OK)) + FATAL("-m32 is not supported by your compiler"); + + } + + break; + + case 64: + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-compiler-rt-64.o", obj_path); + if (access(cc_params[cc_par_cnt - 1], R_OK)) + FATAL("-m64 is not supported by your compiler"); + if (lto_mode) { + + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-rt-lto-64.o", obj_path); + if (access(cc_params[cc_par_cnt - 1], R_OK)) + FATAL("-m64 is not supported by your compiler"); + + } + + break; + + } + + #ifndef __APPLE__ + if (!shared_linking) + cc_params[cc_par_cnt++] = + alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); + #endif + + } + +#endif + + cc_params[cc_par_cnt] = NULL; + +} + +/* Main entry point */ + +int main(int argc, char **argv, char **envp) { + + int i; + char *callname = argv[0], *ptr = NULL; + + if (getenv("AFL_DEBUG")) { + + debug = 1; + if (strcmp(getenv("AFL_DEBUG"), "0") == 0) unsetenv("AFL_DEBUG"); + + } else if (getenv("AFL_QUIET")) + + be_quiet = 1; + + if ((ptr = strrchr(callname, '/')) != NULL) callname = ptr + 1; + argvnull = (u8 *)argv[0]; + check_environment_vars(envp); + + if ((ptr = find_object("as", argv[0])) != NULL) { + + have_gcc = 1; + ck_free(ptr); + + } + +#if (LLVM_MAJOR > 2) + + if ((ptr = find_object("SanitizerCoverageLTO.so", argv[0])) != NULL) { + + have_lto = 1; + ck_free(ptr); + + } + + if ((ptr = find_object("cmplog-routines-pass.so", argv[0])) != NULL) { + + have_llvm = 1; + ck_free(ptr); + + } + +#endif + + if ((ptr = find_object("afl-gcc-pass.so", argv[0])) != NULL) { + + have_gcc_plugin = 1; + ck_free(ptr); + + } + +#if (LLVM_MAJOR > 2) + + if (strncmp(callname, "afl-clang-fast", 14) == 0) { + + compiler_mode = LLVM; + + } else if (strncmp(callname, "afl-clang-lto", 13) == 0 || + + strncmp(callname, "afl-lto", 7) == 0) { + + compiler_mode = LTO; + + } else + +#endif + if (strncmp(callname, "afl-gcc-fast", 12) == 0 || + + strncmp(callname, "afl-g++-fast", 12) == 0) { + + compiler_mode = GCC_PLUGIN; + + } else if (strncmp(callname, "afl-gcc", 7) == 0 || + + strncmp(callname, "afl-g++", 7) == 0) { + + compiler_mode = GCC; + + } + + if ((ptr = getenv("AFL_CC_COMPILER"))) { + + if (compiler_mode) { + + WARNF( + "\"AFL_CC_COMPILER\" is set but a specific compiler was already " + "selected by command line parameter or symlink, ignoring the " + "environment variable!"); + + } else { + + if (strncasecmp(ptr, "LTO", 3) == 0) { + + compiler_mode = LTO; + + } else if (strncasecmp(ptr, "LLVM", 4) == 0) { + + compiler_mode = LLVM; + + } else if (strncasecmp(ptr, "GCC_P", 5) == 0 || + + strncasecmp(ptr, "GCC-P", 5) == 0 || + strncasecmp(ptr, "GCCP", 4) == 0) { + + compiler_mode = GCC_PLUGIN; + + } else if (strcasecmp(ptr, "GCC") == 0) { + + compiler_mode = GCC; + + } else + + FATAL("Unknown AFL_CC_COMPILER mode: %s\n", ptr); + + } + + } + + for (i = 1; i < argc; i++) { + + if (strncmp(argv[i], "--afl", 5) == 0) { + + if (compiler_mode) + WARNF( + "--afl-... compiler mode supersedes the AFL_CC_COMPILER and " + "symlink compiler selection!"); + + ptr = argv[i]; + ptr += 5; + while (*ptr == '-') + ptr++; + + if (strncasecmp(ptr, "LTO", 3) == 0) { + + compiler_mode = LTO; + + } else if (strncasecmp(ptr, "LLVM", 4) == 0) { + + compiler_mode = LLVM; + + } else if (strncasecmp(ptr, "GCC_P", 5) == 0 || + + strncasecmp(ptr, "GCC-P", 5) == 0 || + strncasecmp(ptr, "GCCP", 4) == 0) { + + compiler_mode = GCC_PLUGIN; + + } else if (strcasecmp(ptr, "GCC") == 0) { + + compiler_mode = GCC; + + } else + + FATAL("Unknown --afl-... compiler mode: %s\n", argv[i]); + + } + + } + + if (strlen(callname) > 2 && + (strncmp(callname + strlen(callname) - 2, "++", 2) == 0 || + strstr(callname, "-g++") != NULL)) + plusplus_mode = 1; + + if (getenv("USE_TRACE_PC") || getenv("AFL_USE_TRACE_PC") || + getenv("AFL_LLVM_USE_TRACE_PC") || getenv("AFL_TRACE_PC")) { + + if (instrument_mode == 0) + instrument_mode = INSTRUMENT_PCGUARD; + else if (instrument_mode != INSTRUMENT_PCGUARD) + FATAL("you can not set AFL_LLVM_INSTRUMENT and AFL_TRACE_PC together"); + + } + + if ((getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || + getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") || + getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) && + getenv("AFL_DONT_OPTIMIZE")) + WARNF( + "AFL_LLVM_ALLOWLIST/DENYLIST and AFL_DONT_OPTIMIZE cannot be combined " + "for file matching, only function matching!"); + + if (getenv("AFL_LLVM_INSTRIM") || getenv("INSTRIM") || + getenv("INSTRIM_LIB")) { + + if (instrument_mode == 0) + instrument_mode = INSTRUMENT_CFG; + else if (instrument_mode != INSTRUMENT_CFG) + FATAL( + "you can not set AFL_LLVM_INSTRUMENT and AFL_LLVM_INSTRIM together"); + + } + + if (getenv("AFL_LLVM_CTX")) instrument_opt_mode |= INSTRUMENT_OPT_CTX; + + if (getenv("AFL_LLVM_NGRAM_SIZE")) { + + instrument_opt_mode |= INSTRUMENT_OPT_NGRAM; + ngram_size = atoi(getenv("AFL_LLVM_NGRAM_SIZE")); + if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX) + FATAL( + "NGRAM instrumentation mode must be between 2 and NGRAM_SIZE_MAX " + "(%u)", + NGRAM_SIZE_MAX); + + } + + if (getenv("AFL_LLVM_INSTRUMENT")) { + + u8 *ptr = strtok(getenv("AFL_LLVM_INSTRUMENT"), ":,;"); + + while (ptr) { + + if (strncasecmp(ptr, "afl", strlen("afl")) == 0 || + strncasecmp(ptr, "classic", strlen("classic")) == 0) { + + if (instrument_mode == INSTRUMENT_LTO) { + + instrument_mode = INSTRUMENT_CLASSIC; + lto_mode = 1; + + } else if (!instrument_mode || instrument_mode == INSTRUMENT_AFL) + + instrument_mode = INSTRUMENT_AFL; + else + FATAL("main instrumentation mode already set with %s", + instrument_mode_string[instrument_mode]); + + } + + if (strncasecmp(ptr, "pc-guard", strlen("pc-guard")) == 0 || + strncasecmp(ptr, "pcguard", strlen("pcguard")) == 0) { + + if (!instrument_mode || instrument_mode == INSTRUMENT_PCGUARD) + instrument_mode = INSTRUMENT_PCGUARD; + else + FATAL("main instrumentation mode already set with %s", + instrument_mode_string[instrument_mode]); + + } + + if (strncasecmp(ptr, "cfg", strlen("cfg")) == 0 || + strncasecmp(ptr, "instrim", strlen("instrim")) == 0) { + + if (instrument_mode == INSTRUMENT_LTO) { + + instrument_mode = INSTRUMENT_CFG; + lto_mode = 1; + + } else if (!instrument_mode || instrument_mode == INSTRUMENT_CFG) + + instrument_mode = INSTRUMENT_CFG; + else + FATAL("main instrumentation mode already set with %s", + instrument_mode_string[instrument_mode]); + + } + + if (strncasecmp(ptr, "lto", strlen("lto")) == 0) { + + lto_mode = 1; + if (!instrument_mode || instrument_mode == INSTRUMENT_LTO) + instrument_mode = INSTRUMENT_LTO; + else if (instrument_mode != INSTRUMENT_CFG) + FATAL("main instrumentation mode already set with %s", + instrument_mode_string[instrument_mode]); + + } + + if (strncasecmp(ptr, "ctx", strlen("ctx")) == 0) { + + instrument_opt_mode |= INSTRUMENT_OPT_CTX; + setenv("AFL_LLVM_CTX", "1", 1); + + } + + if (strncasecmp(ptr, "ngram", strlen("ngram")) == 0) { + + ptr += strlen("ngram"); + while (*ptr && (*ptr < '0' || *ptr > '9')) + ptr++; + + if (!*ptr) { + + if ((ptr = getenv("AFL_LLVM_NGRAM_SIZE")) != NULL) + FATAL( + "you must set the NGRAM size with (e.g. for value 2) " + "AFL_LLVM_INSTRUMENT=ngram-2"); + + } + + ngram_size = atoi(ptr); + if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX) + FATAL( + "NGRAM instrumentation option must be between 2 and " + "NGRAM_SIZE_MAX " + "(%u)", + NGRAM_SIZE_MAX); + instrument_opt_mode |= (INSTRUMENT_OPT_NGRAM); + ptr = alloc_printf("%u", ngram_size); + setenv("AFL_LLVM_NGRAM_SIZE", ptr, 1); + + } + + ptr = strtok(NULL, ":,;"); + + } + + } + + if (!compiler_mode) { + + // lto is not a default because outside of afl-cc RANLIB and AR have to + // be set to llvm versions so this would work + if (have_llvm) + compiler_mode = LLVM; + else if (have_gcc_plugin) + compiler_mode = GCC_PLUGIN; + else if (have_gcc) + compiler_mode = GCC; + else if (have_lto) + compiler_mode = LTO; + else + FATAL("no compiler mode available"); + + } + + if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) { + + char *fp; + fp = realpath(argv[0], NULL); + + printf("afl-cc" VERSION + " by Michal Zalewski, Laszlo Szekeres, Marc Heuse\n"); + + SAYF( + "\n" + "afl-cc/afl-c++ [options]\n" + "\n" + "This is a helper application for afl-fuzz. It serves as a drop-in " + "replacement\n" + "for gcc and clang, letting you recompile third-party code with the " + "required\n" + "runtime instrumentation. A common use pattern would be one of the " + "following:\n\n" + + " CC=afl-cc CXX=afl-c++ ./configure --disable-shared\n" + " cmake -DCMAKE_C_COMPILERC=afl-cc -DCMAKE_CXX_COMPILER=afl-c++ .\n" + " CC=afl-cc CXX=afl-c++ meson\n\n"); + + SAYF( + " |---------------- FEATURES " + "---------------|\n" + "MODES: NCC PERSIST SNAP DICT LAF " + "CMPLOG SELECT\n" + " [LTO] llvm LTO: %s%s\n" + " PCGUARD DEFAULT yes yes yes yes yes yes " + " yes\n" + " CLASSIC yes yes yes yes yes yes " + " yes\n" + " [LLVM] llvm: %s%s\n" + " PCGUARD %s yes yes yes module yes yes " + "extern\n" + " CLASSIC %s no yes yes module yes yes " + "yes\n" + " - NORMAL\n" + " - CTX\n" + " - NGRAM-{2-16}\n" + " INSTRIM no yes yes module yes yes " + " yes\n" + " - NORMAL\n" + " - CTX\n" + " - NGRAM-{2-16}\n" + " [GCC_PLUGIN] gcc plugin: %s%s\n" + " CLASSIC DEFAULT no yes yes no no no " + " simple\n" + " [GCC] simple gcc: %s%s\n" + " CLASSIC DEFAULT no no no no no no " + " no\n\n", + have_lto ? "AVAILABLE" : "unavailable!", + compiler_mode == LTO ? " [SELECTED]" : "", + have_llvm ? "AVAILABLE" : "unavailable!", + compiler_mode == LLVM ? " [SELECTED]" : "", + LLVM_MAJOR > 6 ? "DEFAULT" : " ", + LLVM_MAJOR > 6 ? " " : "DEFAULT", + have_gcc_plugin ? "AVAILABLE" : "unavailable!", + compiler_mode == GCC_PLUGIN ? " [SELECTED]" : "", + have_gcc ? "AVAILABLE" : "unavailable!", + compiler_mode == GCC ? " [SELECTED]" : ""); + + SAYF( + "Modes:\n" + " To select the compiler mode use a symlink version (e.g. " + "afl-clang-fast), set\n" + " the environment variable AFL_CC_COMPILER to a mode (e.g. LLVM) or " + "use the\n" + " command line parameter --afl-MODE (e.g. --afl-llvm). If none is " + "selected,\n" + " afl-cc will select the best available (LLVM -> GCC_PLUGIN -> GCC).\n" + " The best is LTO but it often needs RANLIB and AR settings outside " + "of afl-cc.\n\n"); + + SAYF( + "Sub-Modes: (set via env AFL_LLVM_INSTRUMENT, afl-cc selects the best " + "available)\n" + " PCGUARD: Dominator tree instrumentation (best!) (README.llvm.md)\n" + " CLASSIC: decision target instrumentation (README.llvm.md)\n" + " CTX: CLASSIC + callee context (instrumentation/README.ctx.md)\n" + " NGRAM-x: CLASSIC + previous path " + "((instrumentation/README.ngram.md)\n" + " INSTRIM: Dominator tree (for LLVM <= 6.0) " + "(instrumentation/README.instrim.md)\n\n"); + + SAYF( + "Features: (see documentation links)\n" + " NCC: non-colliding coverage [automatic] (that is an amazing " + "thing!)\n" + " (instrumentation/README.lto.md)\n" + " PERSIST: persistent mode support [code] (huge speed increase!)\n" + " (instrumentation/README.persistent_mode.md)\n" + " SNAP: linux lkm snapshot module support [automatic] (speed " + "increase)\n" + " (https://github.com/AFLplusplus/AFL-Snapshot-LKM/)\n" + " DICT: dictionary in the target [yes=automatic or llvm module " + "pass]\n" + " (instrumentation/README.lto.md + " + "instrumentation/README.llvm.md)\n" + " LAF: comparison splitting [env] " + "(instrumentation/README.laf-intel.md)\n" + " CMPLOG: input2state exploration [env] " + "(instrumentation/README.cmplog.md)\n" + " SELECT: selective instrumentation (allow/deny) on filename or " + "function [env]\n" + " (instrumentation/README.instrument_list.md)\n\n"); + + if (argc < 2 || strncmp(argv[1], "-hh", 3)) { + + SAYF( + "To see all environment variables for the configuration of afl-cc " + "use \"-hh\".\n"); + + } else { + + SAYF( + "Environment variables used:\n" + " AFL_CC: path to the C compiler to use\n" + " AFL_CXX: path to the C++ compiler to use\n" + " AFL_DEBUG: enable developer debugging output\n" + " AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" + " AFL_HARDEN: adds code hardening to catch memory bugs\n" + " AFL_INST_RATIO: percentage of branches to instrument\n" +#if LLVM_MAJOR < 9 + " AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n" +#else + " AFL_LLVM_SKIP_NEVERZERO: do not skip zero on trace counters\n" +#endif + " AFL_LLVM_DICT2FILE: generate an afl dictionary based on found " + "comparisons\n" + " AFL_LLVM_LAF_ALL: enables all LAF splits/transforms\n" + " AFL_LLVM_LAF_SPLIT_COMPARES: enable cascaded comparisons\n" + " AFL_LLVM_LAF_SPLIT_COMPARES_BITW: size limit (default 8)\n" + " AFL_LLVM_LAF_SPLIT_SWITCHES: cascaded comparisons on switches\n" + " AFL_LLVM_LAF_SPLIT_FLOATS: cascaded comparisons on floats\n" + " AFL_LLVM_LAF_TRANSFORM_COMPARES: cascade comparisons for string " + "functions\n" + " AFL_LLVM_INSTRUMENT_ALLOW/AFL_LLVM_INSTRUMENT_DENY: enable " + "instrument allow/\n" + " deny listing (selective instrumentation)\n" + " AFL_NO_BUILTIN: no builtins for string compare functions (for " + "libtokencap.so)\n" + " AFL_PATH: path to instrumenting pass and runtime " + "(afl-compiler-rt.*o)\n" + " AFL_LLVM_DOCUMENT_IDS: document edge IDs given to which function " + "(LTO only)\n" + " AFL_QUIET: suppress verbose output\n" + " AFL_USE_ASAN: activate address sanitizer\n" + " AFL_USE_CFISAN: activate control flow sanitizer\n" + " AFL_USE_MSAN: activate memory sanitizer\n" + " AFL_USE_UBSAN: activate undefined behaviour sanitizer\n", + BIN_PATH, BIN_PATH); + + SAYF( + "\nLLVM/LTO/afl-clang-fast/afl-clang-lto specific environment " + "variables:\n" + " AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen mutator)\n" + " AFL_LLVM_INSTRUMENT: set instrumentation mode: CLASSIC, INSTRIM, " + "PCGUARD, LTO, CTX, NGRAM-2 ... NGRAM-16\n" + " You can also use the old environment variables instead:\n" + " AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n" + " AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n" + " AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed " + "(option to INSTRIM)\n" + " AFL_LLVM_CTX: use context sensitive coverage (for CLASSIC and " + "INSTRIM)\n" + " AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage (for " + "CLASSIC and INSTRIM)\n"); + +#ifdef AFL_CLANG_FLTO + SAYF( + "\nLTO/afl-clang-lto specific environment variables:\n" + "AFL_LLVM_MAP_ADDR: use a fixed coverage map address (speed), e.g. " + "0x10000\n" + "AFL_LLVM_DOCUMENT_IDS: write all edge IDs and the corresponding " + "functions they are in into this file\n" + "AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a " + "global var\n" + "AFL_LLVM_LTO_STARTID: from which ID to start counting from for a " + "bb\n" + "AFL_REAL_LD: use this lld linker instead of the compiled in path\n" + "\nafl-clang-lto was built with linker target \"%s\" and LTO flags " + "\"%s\"\n" + "If anything fails - be sure to read README.lto.md!\n", + AFL_REAL_LD, AFL_CLANG_FLTO); +#endif + + } + + SAYF( + "For any information on the available instrumentations and options " + "please \n" + "consult the README.md, especially section 3.1 about instrumenting " + "targets.\n\n"); + +#if (LLVM_MAJOR > 2) + if (have_lto) + SAYF("afl-cc LTO with ld=%s %s\n", AFL_REAL_LD, AFL_CLANG_FLTO); + if (have_llvm) + SAYF("afl-cc LLVM version %d with the the binary path \"%s\".\n", + LLVM_MAJOR, LLVM_BINDIR); + if (have_lto || have_llvm) SAYF("\n"); +#endif + + SAYF( + "Do not be overwhelmed :) afl-cc uses good defaults if no options are " + "selected.\n" + "Read the documentation for FEATURES though, all are good but few are " + "defaults.\n\n"); + + exit(1); + + } + + if (compiler_mode == LTO) { + + if (instrument_mode == 0 || instrument_mode == INSTRUMENT_LTO || + instrument_mode == INSTRUMENT_CFG) { + + lto_mode = 1; + if (!instrument_mode) { + + instrument_mode = INSTRUMENT_CFG; + ptr = instrument_mode_string[instrument_mode]; + + } + + } else if (instrument_mode == INSTRUMENT_LTO || + + instrument_mode == INSTRUMENT_CLASSIC) { + + lto_mode = 1; + + } else { + + if (!be_quiet) + WARNF("afl-clang-lto called with mode %s, using that mode instead", + instrument_mode_string[instrument_mode]); + + } + + } + + if (instrument_mode == 0 && compiler_mode < GCC_PLUGIN) { + +#if LLVM_MAJOR <= 6 + instrument_mode = INSTRUMENT_AFL; +#else + if (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || + getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") || + getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) { + + instrument_mode = INSTRUMENT_AFL; + WARNF( + "switching to classic instrumentation because " + "AFL_LLVM_ALLOWLIST/DENYLIST does not work with PCGUARD. Use " + "-fsanitize-coverage-allowlist=allowlist.txt or " + "-fsanitize-coverage-blocklist=denylist.txt if you want to use " + "PCGUARD. Requires llvm 12+. See https://clang.llvm.org/docs/ " + "SanitizerCoverage.html#partially-disabling-instrumentation"); + + } else + + instrument_mode = INSTRUMENT_PCGUARD; +#endif + + } + + if (instrument_opt_mode && compiler_mode != LLVM) + FATAL("CTX and NGRAM can only be used in LLVM mode"); + + if (!instrument_opt_mode) { + + if (lto_mode && instrument_mode == INSTRUMENT_CFG) + instrument_mode = INSTRUMENT_PCGUARD; + ptr = instrument_mode_string[instrument_mode]; + + } else { + + if (instrument_opt_mode == INSTRUMENT_OPT_CTX) + + ptr = alloc_printf("%s + CTX", instrument_mode_string[instrument_mode]); + else if (instrument_opt_mode == INSTRUMENT_OPT_NGRAM) + ptr = alloc_printf("%s + NGRAM-%u", + instrument_mode_string[instrument_mode], ngram_size); + else + ptr = alloc_printf("%s + CTX + NGRAM-%u", + instrument_mode_string[instrument_mode], ngram_size); + + } + +#ifndef AFL_CLANG_FLTO + if (lto_mode) + FATAL( + "instrumentation mode LTO specified but LLVM support not available " + "(requires LLVM 11 or higher)"); +#endif + + if (instrument_opt_mode && instrument_mode != INSTRUMENT_CLASSIC && + instrument_mode != INSTRUMENT_CFG) + FATAL( + "CTX and NGRAM instrumentation options can only be used with CFG " + "(recommended) and CLASSIC instrumentation modes!"); + + if (getenv("AFL_LLVM_SKIP_NEVERZERO") && getenv("AFL_LLVM_NOT_ZERO")) + FATAL( + "AFL_LLVM_NOT_ZERO and AFL_LLVM_SKIP_NEVERZERO can not be set " + "together"); + + if (instrument_mode == INSTRUMENT_PCGUARD && + (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || + getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") || + getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST"))) + FATAL( + "Instrumentation type PCGUARD does not support " + "AFL_LLVM_ALLOWLIST/DENYLIST! Use " + "-fsanitize-coverage-allowlist=allowlist.txt or " + "-fsanitize-coverage-blocklist=denylist.txt instead (requires llvm " + "12+), see " + "https://clang.llvm.org/docs/" + "SanitizerCoverage.html#partially-disabling-instrumentation"); + + u8 *ptr2; + + if ((ptr2 = getenv("AFL_LLVM_DICT2FILE")) != NULL && *ptr2 != '/') + FATAL("AFL_LLVM_DICT2FILE must be set to an absolute file path"); + + if ((isatty(2) && !be_quiet) || debug) { + + SAYF(cCYA + "afl-cc " VERSION cRST + " by Michal Zalewski, Laszlo Szekeres, Marc Heuse - mode: %s-%s\n", + compiler_mode_string[compiler_mode], ptr); + + } + + if (!be_quiet && !lto_mode && + ((ptr2 = getenv("AFL_MAP_SIZE")) || (ptr2 = getenv("AFL_MAPSIZE")))) { + + u32 map_size = atoi(ptr2); + if (map_size != MAP_SIZE) + WARNF("AFL_MAP_SIZE is not supported by afl-clang-fast"); + + } + + if (debug) { + + SAYF(cMGN "[D]" cRST " cd \"%s\";", getthecwd()); + for (i = 0; i < argc; i++) + SAYF(" \"%s\"", argv[i]); + SAYF("\n"); + + } + + if (getenv("AFL_LLVM_LAF_ALL")) { + + setenv("AFL_LLVM_LAF_SPLIT_SWITCHES", "1", 1); + setenv("AFL_LLVM_LAF_SPLIT_COMPARES", "1", 1); + setenv("AFL_LLVM_LAF_SPLIT_FLOATS", "1", 1); + setenv("AFL_LLVM_LAF_TRANSFORM_COMPARES", "1", 1); + + } + + cmplog_mode = getenv("AFL_CMPLOG") || getenv("AFL_LLVM_CMPLOG"); + if (!be_quiet && cmplog_mode) + printf("CmpLog mode by \n"); + +#ifndef __ANDROID__ + find_obj(argv[0]); +#endif + + edit_params(argc, argv, envp); + + if (debug) { + + SAYF(cMGN "[D]" cRST " cd \"%s\";", getthecwd()); + for (i = 0; i < cc_par_cnt; i++) + SAYF(" \"%s\"", cc_params[i]); + SAYF("\n"); + + } + + execvp(cc_params[0], (char **)cc_params); + + FATAL("Oops, failed to execute '%s' - check your PATH", cc_params[0]); + + return 0; + +} + diff --git a/src/afl-gcc.c b/src/afl-gcc.c deleted file mode 100644 index 97564aea..00000000 --- a/src/afl-gcc.c +++ /dev/null @@ -1,488 +0,0 @@ -/* - american fuzzy lop++ - wrapper for GCC and clang - ------------------------------------------------ - - Originally written by Michal Zalewski - - Now maintained by Marc Heuse , - Heiko Eißfeldt and - Andrea Fioraldi - - Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 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. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - This program is a drop-in replacement for GCC or clang. The most common way - of using it is to pass the path to afl-gcc or afl-clang via CC when invoking - ./configure. - - (Of course, use CXX and point it to afl-g++ / afl-clang++ for C++ code.) - - The wrapper needs to know the path to afl-as (renamed to 'as'). The default - is /usr/local/lib/afl/. A convenient way to specify alternative directories - would be to set AFL_PATH. - - If AFL_HARDEN is set, the wrapper will compile the target app with various - hardening options that may help detect memory management issues more - reliably. You can also specify AFL_USE_ASAN to enable ASAN. - - If you want to call a non-default compiler as a next step of the chain, - specify its location via AFL_CC or AFL_CXX. - - */ - -#define AFL_MAIN - -#include "config.h" -#include "types.h" -#include "debug.h" -#include "alloc-inl.h" - -#include -#include -#include -#include - -static u8 * as_path; /* Path to the AFL 'as' wrapper */ -static u8 **cc_params; /* Parameters passed to the real CC */ -static u32 cc_par_cnt = 1; /* Param count, including argv0 */ -static u8 be_quiet, /* Quiet mode */ - clang_mode; /* Invoked as afl-clang*? */ - -/* Try to find our "fake" GNU assembler in AFL_PATH or at the location derived - from argv[0]. If that fails, abort. */ - -static void find_as(u8 *argv0) { - - u8 *afl_path = getenv("AFL_PATH"); - u8 *slash, *tmp; - - if (afl_path) { - - tmp = alloc_printf("%s/as", afl_path); - - if (!access(tmp, X_OK)) { - - as_path = afl_path; - ck_free(tmp); - return; - - } - - ck_free(tmp); - - } - - slash = strrchr(argv0, '/'); - - if (slash) { - - u8 *dir; - - *slash = 0; - dir = ck_strdup(argv0); - *slash = '/'; - - tmp = alloc_printf("%s/afl-as", dir); - - if (!access(tmp, X_OK)) { - - as_path = dir; - ck_free(tmp); - return; - - } - - ck_free(tmp); - ck_free(dir); - - } - - if (!access(AFL_PATH "/as", X_OK)) { - - as_path = AFL_PATH; - return; - - } - - FATAL("Unable to find AFL wrapper binary for 'as'. Please set AFL_PATH"); - -} - -/* Copy argv to cc_params, making the necessary edits. */ - -static void edit_params(u32 argc, char **argv) { - - u8 fortify_set = 0, asan_set = 0; - u8 *name; - -#if defined(__FreeBSD__) && defined(WORD_SIZE_64) - u8 m32_set = 0; -#endif - - cc_params = ck_alloc((argc + 128) * sizeof(u8 *)); - - name = strrchr(argv[0], '/'); - if (!name) { - - name = argv[0]; - - /* This should never happen but fixes a scan-build warning */ - if (!name) { FATAL("Empty argv set"); } - - } else { - - ++name; - - } - - if (!strncmp(name, "afl-clang", 9)) { - - clang_mode = 1; - - setenv(CLANG_ENV_VAR, "1", 1); - - if (!strcmp(name, "afl-clang++")) { - - u8 *alt_cxx = getenv("AFL_CXX"); - cc_params[0] = alt_cxx && *alt_cxx ? alt_cxx : (u8 *)"clang++"; - - } else if (!strcmp(name, "afl-clang")) { - - u8 *alt_cc = getenv("AFL_CC"); - cc_params[0] = alt_cc && *alt_cc ? alt_cc : (u8 *)"clang"; - - } else { - - fprintf(stderr, "Name of the binary: %s\n", argv[0]); - FATAL("Name of the binary is not a known name, expected afl-clang(++)"); - - } - - } else { - - /* With GCJ and Eclipse installed, you can actually compile Java! The - instrumentation will work (amazingly). Alas, unhandled exceptions do - not call abort(), so afl-fuzz would need to be modified to equate - non-zero exit codes with crash conditions when working with Java - binaries. Meh. */ - -#ifdef __APPLE__ - - if (!strcmp(name, "afl-g++")) { - - cc_params[0] = getenv("AFL_CXX"); - - } else if (!strcmp(name, "afl-gcj")) { - - cc_params[0] = getenv("AFL_GCJ"); - - } else if (!strcmp(name, "afl-gcc")) { - - cc_params[0] = getenv("AFL_CC"); - - } else { - - fprintf(stderr, "Name of the binary: %s\n", argv[0]); - FATAL("Name of the binary is not a known name, expected afl-gcc/g++/gcj"); - - } - - if (!cc_params[0]) { - - SAYF("\n" cLRD "[-] " cRST - "On Apple systems, 'gcc' is usually just a wrapper for clang. " - "Please use the\n" - " 'afl-clang' utility instead of 'afl-gcc'. If you really have " - "GCC installed,\n" - " set AFL_CC or AFL_CXX to specify the correct path to that " - "compiler.\n"); - - FATAL("AFL_CC or AFL_CXX required on MacOS X"); - - } - -#else - - if (!strcmp(name, "afl-g++")) { - - u8 *alt_cxx = getenv("AFL_CXX"); - cc_params[0] = alt_cxx && *alt_cxx ? alt_cxx : (u8 *)"g++"; - - } else if (!strcmp(name, "afl-gcj")) { - - u8 *alt_cc = getenv("AFL_GCJ"); - cc_params[0] = alt_cc && *alt_cc ? alt_cc : (u8 *)"gcj"; - - } else if (!strcmp(name, "afl-gcc")) { - - u8 *alt_cc = getenv("AFL_CC"); - cc_params[0] = alt_cc && *alt_cc ? alt_cc : (u8 *)"gcc"; - - } else { - - fprintf(stderr, "Name of the binary: %s\n", argv[0]); - FATAL("Name of the binary is not a known name, expected afl-gcc/g++/gcj"); - - } - -#endif /* __APPLE__ */ - - } - - while (--argc) { - - u8 *cur = *(++argv); - - if (!strncmp(cur, "-B", 2)) { - - if (!be_quiet) { WARNF("-B is already set, overriding"); } - - if (!cur[2] && argc > 1) { - - argc--; - argv++; - - } - - continue; - - } - - if (!strcmp(cur, "-integrated-as")) { continue; } - - if (!strcmp(cur, "-pipe")) { continue; } - -#if defined(__FreeBSD__) && defined(WORD_SIZE_64) - if (!strcmp(cur, "-m32")) m32_set = 1; -#endif - - if (!strcmp(cur, "-fsanitize=address") || - !strcmp(cur, "-fsanitize=memory")) { - - asan_set = 1; - - } - - if (strstr(cur, "FORTIFY_SOURCE")) { fortify_set = 1; } - - cc_params[cc_par_cnt++] = cur; - - } - - cc_params[cc_par_cnt++] = "-B"; - cc_params[cc_par_cnt++] = as_path; - - if (clang_mode) { cc_params[cc_par_cnt++] = "-no-integrated-as"; } - - if (getenv("AFL_HARDEN")) { - - cc_params[cc_par_cnt++] = "-fstack-protector-all"; - - if (!fortify_set) { cc_params[cc_par_cnt++] = "-D_FORTIFY_SOURCE=2"; } - - } - - if (asan_set) { - - /* Pass this on to afl-as to adjust map density. */ - - setenv("AFL_USE_ASAN", "1", 1); - - } else if (getenv("AFL_USE_ASAN")) { - - if (getenv("AFL_USE_MSAN")) { - - FATAL("ASAN and MSAN are mutually exclusive"); - - } - - if (getenv("AFL_HARDEN")) { - - FATAL("ASAN and AFL_HARDEN are mutually exclusive"); - - } - - cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE"; - cc_params[cc_par_cnt++] = "-fsanitize=address"; - - } else if (getenv("AFL_USE_MSAN")) { - - if (getenv("AFL_USE_ASAN")) { - - FATAL("ASAN and MSAN are mutually exclusive"); - - } - - if (getenv("AFL_HARDEN")) { - - FATAL("MSAN and AFL_HARDEN are mutually exclusive"); - - } - - cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE"; - cc_params[cc_par_cnt++] = "-fsanitize=memory"; - - } - - if (getenv("AFL_USE_UBSAN")) { - - cc_params[cc_par_cnt++] = "-fsanitize=undefined"; - cc_params[cc_par_cnt++] = "-fsanitize-undefined-trap-on-error"; - cc_params[cc_par_cnt++] = "-fno-sanitize-recover=all"; - - } - -#if defined(USEMMAP) && !defined(__HAIKU__) - cc_params[cc_par_cnt++] = "-lrt"; -#endif - - if (!getenv("AFL_DONT_OPTIMIZE")) { - -#if defined(__FreeBSD__) && defined(WORD_SIZE_64) - - /* On 64-bit FreeBSD systems, clang -g -m32 is broken, but -m32 itself - works OK. This has nothing to do with us, but let's avoid triggering - that bug. */ - - if (!clang_mode || !m32_set) cc_params[cc_par_cnt++] = "-g"; - -#else - - cc_params[cc_par_cnt++] = "-g"; - -#endif - - cc_params[cc_par_cnt++] = "-O3"; - cc_params[cc_par_cnt++] = "-funroll-loops"; - - /* Two indicators that you're building for fuzzing; one of them is - AFL-specific, the other is shared with libfuzzer. */ - - cc_params[cc_par_cnt++] = "-D__AFL_COMPILER=1"; - cc_params[cc_par_cnt++] = "-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1"; - - } - - if (getenv("AFL_NO_BUILTIN")) { - - cc_params[cc_par_cnt++] = "-fno-builtin-strcmp"; - cc_params[cc_par_cnt++] = "-fno-builtin-strncmp"; - cc_params[cc_par_cnt++] = "-fno-builtin-strcasecmp"; - cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp"; - cc_params[cc_par_cnt++] = "-fno-builtin-memcmp"; - cc_params[cc_par_cnt++] = "-fno-builtin-bcmp"; - cc_params[cc_par_cnt++] = "-fno-builtin-strstr"; - cc_params[cc_par_cnt++] = "-fno-builtin-strcasestr"; - - } - - cc_params[cc_par_cnt] = NULL; - -} - -/* Main entry point */ - -int main(int argc, char **argv) { - - char *env_info = - "Environment variables used by afl-gcc:\n" - "AFL_CC: path to the C compiler to use\n" - "AFL_CXX: path to the C++ compiler to use\n" - "AFL_GCJ: path to the java compiler to use\n" - "AFL_PATH: path to the instrumenting assembler\n" - "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" - "AFL_NO_BUILTIN: compile for use with libtokencap.so\n" - "AFL_QUIET: suppress verbose output\n" - "AFL_CAL_FAST: speed up the initial calibration\n" - "AFL_HARDEN: adds code hardening to catch memory bugs\n" - "AFL_USE_ASAN: activate address sanitizer\n" - "AFL_USE_MSAN: activate memory sanitizer\n" - "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n" - - "\nEnvironment variables used by afl-as (called by afl-gcc):\n" - "AFL_AS: path to the assembler to use\n" - "TMPDIR: set the directory for temporary files of afl-as\n" - "TEMP: fall back path to directory for temporary files\n" - "TMP: fall back path to directory for temporary files\n" - "AFL_INST_RATIO: percentage of branches to instrument\n" - "AFL_QUIET: suppress verbose output\n" - "AFL_KEEP_ASSEMBLY: leave instrumented assembly files\n" - "AFL_AS_FORCE_INSTRUMENT: force instrumentation for asm sources\n"; - - if (argc == 2 && strncmp(argv[1], "-h", 2) == 0) { - - printf("afl-cc" VERSION " by Michal Zalewski\n\n"); - printf("%s \n\n", argv[0]); - printf("afl-gcc has no command line options\n\n%s\n", env_info); - printf( - "NOTE: afl-gcc is deprecated, llvm_mode is much faster and has more " - "options\n"); - return -1; - - } - - if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) { - - SAYF(cCYA "afl-cc" VERSION cRST " by Michal Zalewski\n"); - SAYF(cYEL "[!] " cBRI "NOTE: " cRST - "afl-gcc is deprecated, llvm_mode is much faster and has more " - "options\n"); - - } else { - - be_quiet = 1; - - } - - if (argc < 2) { - - SAYF( - "\n" - "This is a helper application for afl-fuzz. It serves as a drop-in " - "replacement\n" - "for gcc or clang, letting you recompile third-party code with the " - "required\n" - "runtime instrumentation. A common use pattern would be one of the " - "following:\n\n" - - " CC=%s/afl-gcc ./configure\n" - " CXX=%s/afl-g++ ./configure\n\n%s" - - , - BIN_PATH, BIN_PATH, env_info); - - exit(1); - - } - - u8 *ptr; - if (!be_quiet && - ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE")))) { - - u32 map_size = atoi(ptr); - if (map_size != MAP_SIZE) { - - WARNF("AFL_MAP_SIZE is not supported by afl-gcc"); - - } - - } - - find_as(argv[0]); - - edit_params(argc, argv); - - execvp(cc_params[0], (char **)cc_params); - - FATAL("Oops, failed to execute '%s' - check your PATH", cc_params[0]); - - return 0; - -} - diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c new file mode 100644 index 00000000..771e2d0d --- /dev/null +++ b/src/afl-ld-lto.c @@ -0,0 +1,358 @@ +/* + american fuzzy lop++ - wrapper for llvm 11+ lld + ----------------------------------------------- + + Written by Marc Heuse for afl++ + + Maintained by Marc Heuse , + Heiko Eißfeldt + Andrea Fioraldi + Dominik Maier + + Copyright 2019-2020 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. + You may obtain a copy of the License at: + + http://www.apache.org/licenses/LICENSE-2.0 + + The sole purpose of this wrapper is to preprocess clang LTO files when + linking with lld and performing the instrumentation on the whole program. + +*/ + +#define AFL_MAIN +#define _GNU_SOURCE + +#include "config.h" +#include "types.h" +#include "debug.h" +#include "alloc-inl.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#define MAX_PARAM_COUNT 4096 + +static u8 **ld_params; /* Parameters passed to the real 'ld' */ + +static u8 *afl_path = AFL_PATH; +static u8 *real_ld = AFL_REAL_LD; + +static u8 be_quiet, /* Quiet mode (no stderr output) */ + debug, /* AFL_DEBUG */ + passthrough, /* AFL_LD_PASSTHROUGH - no link+optimize*/ + just_version; /* Just show version? */ + +static u32 ld_param_cnt = 1; /* Number of params to 'ld' */ + +/* Examine and modify parameters to pass to 'ld', 'llvm-link' and 'llmv-ar'. + Note that the file name is always the last parameter passed by GCC, + so we exploit this property to keep the code "simple". */ +static void edit_params(int argc, char **argv) { + + u32 i, instrim = 0, gold_pos = 0, gold_present = 0, rt_present = 0, + rt_lto_present = 0, inst_present = 0; + char *ptr; + + ld_params = ck_alloc(4096 * sizeof(u8 *)); + + ld_params[0] = (u8 *)real_ld; + + if (!passthrough) { + + for (i = 1; i < argc; i++) { + + if (strstr(argv[i], "/afl-llvm-rt-lto.o") != NULL) rt_lto_present = 1; + if (strstr(argv[i], "/afl-llvm-rt.o") != NULL) rt_present = 1; + if (strstr(argv[i], "/afl-llvm-lto-instr") != NULL) inst_present = 1; + + } + + for (i = 1; i < argc && !gold_pos; i++) { + + if (strcmp(argv[i], "-plugin") == 0) { + + if (strncmp(argv[i], "-plugin=", strlen("-plugin=")) == 0) { + + if (strcasestr(argv[i], "LLVMgold.so") != NULL) + gold_present = gold_pos = i + 1; + + } else if (i < argc && strcasestr(argv[i + 1], "LLVMgold.so") != NULL) { + + gold_present = gold_pos = i + 2; + + } + + } + + } + + if (!gold_pos) { + + for (i = 1; i + 1 < argc && !gold_pos; i++) { + + if (argv[i][0] != '-') { + + if (argv[i - 1][0] == '-') { + + switch (argv[i - 1][1]) { + + case 'b': + break; + case 'd': + break; + case 'e': + break; + case 'F': + break; + case 'f': + break; + case 'I': + break; + case 'l': + break; + case 'L': + break; + case 'm': + break; + case 'o': + break; + case 'O': + break; + case 'p': + if (index(argv[i - 1], '=') == NULL) gold_pos = i; + break; + case 'R': + break; + case 'T': + break; + case 'u': + break; + case 'y': + break; + case 'z': + break; + case '-': { + + if (strcmp(argv[i - 1], "--oformat") == 0) break; + if (strcmp(argv[i - 1], "--output") == 0) break; + if (strncmp(argv[i - 1], "--opt-remarks-", 14) == 0) break; + gold_pos = i; + break; + + } + + default: + gold_pos = i; + + } + + } else + + gold_pos = i; + + } + + } + + } + + if (!gold_pos) gold_pos = 1; + + } + + if (getenv("AFL_LLVM_INSTRIM")) + instrim = 1; + else if ((ptr = getenv("AFL_LLVM_INSTRUMENT")) && + (strcasestr(ptr, "CFG") == 0 || strcasestr(ptr, "INSTRIM") == 0)) + instrim = 1; + + if (debug) + SAYF(cMGN "[D] " cRST + "passthrough=%s instrim=%d, gold_pos=%d, gold_present=%s " + "inst_present=%s rt_present=%s rt_lto_present=%s\n", + passthrough ? "true" : "false", instrim, gold_pos, + gold_present ? "true" : "false", inst_present ? "true" : "false", + rt_present ? "true" : "false", rt_lto_present ? "true" : "false"); + + for (i = 1; i < argc; i++) { + + if (ld_param_cnt >= MAX_PARAM_COUNT) + FATAL( + "Too many command line parameters because of unpacking .a archives, " + "this would need to be done by hand ... sorry! :-("); + + if (strcmp(argv[i], "--afl") == 0) { + + if (!be_quiet) OKF("afl++ test command line flag detected, exiting."); + exit(0); + + } + + if (i == gold_pos && !passthrough) { + + ld_params[ld_param_cnt++] = alloc_printf("-L%s/../lib", LLVM_BINDIR); + + if (!gold_present) { + + ld_params[ld_param_cnt++] = "-plugin"; + ld_params[ld_param_cnt++] = + alloc_printf("%s/../lib/LLVMgold.so", LLVM_BINDIR); + + } + + ld_params[ld_param_cnt++] = "--allow-multiple-definition"; + + if (!inst_present) { + + if (instrim) + ld_params[ld_param_cnt++] = + alloc_printf("-mllvm=-load=%s/afl-llvm-lto-instrim.so", afl_path); + else + ld_params[ld_param_cnt++] = alloc_printf( + "-mllvm=-load=%s/afl-llvm-lto-instrumentation.so", afl_path); + + } + + if (!rt_present) + ld_params[ld_param_cnt++] = alloc_printf("%s/afl-llvm-rt.o", afl_path); + if (!rt_lto_present) + ld_params[ld_param_cnt++] = + alloc_printf("%s/afl-llvm-rt-lto.o", afl_path); + + } + + ld_params[ld_param_cnt++] = argv[i]; + + } + + ld_params[ld_param_cnt] = NULL; + +} + +/* Main entry point */ + +int main(int argc, char **argv) { + + s32 pid, i, status; + u8 * ptr; + char thecwd[PATH_MAX]; + + if ((ptr = getenv("AFL_LD_CALLER")) != NULL) { + + FATAL("ld loop detected! Set AFL_REAL_LD!\n"); + + } + + if (isatty(2) && !getenv("AFL_QUIET") && !getenv("AFL_DEBUG")) { + + SAYF(cCYA "afl-ld-to" VERSION cRST + " by Marc \"vanHauser\" Heuse \n"); + + } else + + be_quiet = 1; + + if (getenv("AFL_DEBUG") != NULL) debug = 1; + if (getenv("AFL_PATH") != NULL) afl_path = getenv("AFL_PATH"); + if (getenv("AFL_LD_PASSTHROUGH") != NULL) passthrough = 1; + if (getenv("AFL_REAL_LD") != NULL) real_ld = getenv("AFL_REAL_LD"); + + if (!afl_path || !*afl_path) afl_path = "/usr/local/lib/afl"; + + setenv("AFL_LD_CALLER", "1", 1); + + if (debug) { + + if (getcwd(thecwd, sizeof(thecwd)) != 0) strcpy(thecwd, "."); + + SAYF(cMGN "[D] " cRST "cd \"%s\";", thecwd); + for (i = 0; i < argc; i++) + SAYF(" \"%s\"", argv[i]); + SAYF("\n"); + + } + + if (argc < 2) { + + SAYF( + "\n" + "This is a helper application for afl-clang-lto. It is a wrapper " + "around GNU " + "llvm's 'lld',\n" + "executed by the toolchain whenever using " + "afl-clang-lto/afl-clang-lto++.\n" + "You probably don't want to run this program directly but rather pass " + "it as LD parameter to configure scripts\n\n" + + "Environment variables:\n" + " AFL_LD_PASSTHROUGH do not link+optimize == no instrumentation\n" + " AFL_REAL_LD point to the real llvm 11 lld if necessary\n" + + "\nafl-ld-to was compiled with the fixed real 'ld' of %s and the " + "binary path of %s\n\n", + real_ld, LLVM_BINDIR); + + exit(1); + + } + + edit_params(argc, argv); // here most of the magic happens :-) + + if (debug) { + + SAYF(cMGN "[D]" cRST " cd \"%s\";", thecwd); + for (i = 0; i < ld_param_cnt; i++) + SAYF(" \"%s\"", ld_params[i]); + SAYF("\n"); + + } + + if (!(pid = fork())) { + + if (strlen(real_ld) > 1) execvp(real_ld, (char **)ld_params); + execvp("ld", (char **)ld_params); // fallback + FATAL("Oops, failed to execute 'ld' - check your PATH"); + + } + + if (pid < 0) PFATAL("fork() failed"); + + if (waitpid(pid, &status, 0) <= 0) PFATAL("waitpid() failed"); + if (debug) SAYF(cMGN "[D] " cRST "linker result: %d\n", status); + + if (!just_version) { + + if (status == 0) { + + if (!be_quiet) OKF("Linker was successful"); + + } else { + + SAYF(cLRD "[-] " cRST + "Linker failed, please investigate and send a bug report. Most " + "likely an 'ld' option is incompatible with %s.\n", + AFL_CLANG_FLTO); + + } + + } + + exit(WEXITSTATUS(status)); + +} + -- cgit v1.2.3 From 4b3ad5f037ee9a36aa057bf55a69acca1f573922 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 5 Sep 2020 12:32:10 +0200 Subject: add cull queue, -i subdir traversal --- src/afl-fuzz-extras.c | 113 +++++++++++++++++++++++++++++++++++++++++--------- src/afl-fuzz-init.c | 108 +++++++++++++++++++++++++++++++++++++++++------ src/afl-fuzz-one.c | 31 ++------------ src/afl-fuzz-queue.c | 7 ---- src/afl-fuzz.c | 33 +++++++++------ 5 files changed, 213 insertions(+), 79 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index d6c368d1..58ce5b6f 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -101,7 +101,8 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len, if (rptr < lptr || *rptr != '"') { - FATAL("Malformed name=\"value\" pair in line %u.", cur_line); + WARNF("Malformed name=\"value\" pair in line %u.", cur_line); + continue; } @@ -141,13 +142,19 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len, if (*lptr != '"') { - FATAL("Malformed name=\"keyword\" pair in line %u.", cur_line); + WARNF("Malformed name=\"keyword\" pair in line %u.", cur_line); + continue; } ++lptr; - if (!*lptr) { FATAL("Empty keyword in line %u.", cur_line); } + if (!*lptr) { + + WARNF("Empty keyword in line %u.", cur_line); + continue; + + } /* Okay, let's allocate memory and copy data between "...", handling \xNN escaping, \\, and \". */ @@ -169,7 +176,9 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len, case 1 ... 31: case 128 ... 255: - FATAL("Non-printable characters in line %u.", cur_line); + WARNF("Non-printable characters in line %u.", cur_line); + continue; + break; case '\\': @@ -185,7 +194,8 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len, if (*lptr != 'x' || !isxdigit(lptr[1]) || !isxdigit(lptr[2])) { - FATAL("Invalid escaping (not \\xNN) in line %u.", cur_line); + WARNF("Invalid escaping (not \\xNN) in line %u.", cur_line); + continue; } @@ -209,10 +219,11 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len, if (afl->extras[afl->extras_cnt].len > MAX_DICT_FILE) { - FATAL( + WARNF( "Keyword too big in line %u (%s, limit is %s)", cur_line, stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), klen), stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE)); + continue; } @@ -232,14 +243,19 @@ static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len, u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX]; - if (!afl->extras_cnt) { FATAL("No usable files in '%s'", dir); } + if (!afl->extras_cnt) { + + WARNF("No usable data in '%s'", dir); + return; + + } qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data), compare_extras_len); - OKF("Loaded %u extra tokens, size range %s to %s.", afl->extras_cnt, - stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), min_len), - stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), max_len)); + ACTF("Loaded %u extra tokens, size range %s to %s.", afl->extras_cnt, + stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), min_len), + stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), max_len)); if (max_len > 32) { @@ -250,8 +266,8 @@ static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len, if (afl->extras_cnt > afl->max_det_extras) { - OKF("More than %d tokens - will use them probabilistically.", - afl->max_det_extras); + WARNF("More than %d tokens - will use them probabilistically.", + afl->max_det_extras); } @@ -320,9 +336,10 @@ void load_extras(afl_state_t *afl, u8 *dir) { if (st.st_size > MAX_DICT_FILE) { WARNF( - "Extra '%s' is very big (%s, limit is %s)", fn, + "Extra '%s' is too big (%s, limit is %s)", fn, stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), st.st_size), stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE)); + continue; } @@ -370,16 +387,74 @@ static inline u8 memcmp_nocase(u8 *m1, u8 *m2, u32 len) { } -/* Adds a new extra / dict entry. Used for LTO autodict. */ +/* Removes duplicates from the loaded extras. This can happen if multiple files + are loaded */ + +void dedup_extras(afl_state_t *afl) { + + if (afl->extras_cnt < 2) return; + + u32 i, j, orig_cnt = afl->extras_cnt; + + for (i = 0; i < afl->extras_cnt - 1; i++) { + + for (j = i + 1; j < afl->extras_cnt; j++) { + + restart_dedup: + + // if the goto was used we could be at the end of the list + if (j >= afl->extras_cnt || afl->extras[i].len != afl->extras[j].len) + break; + + if (memcmp(afl->extras[i].data, afl->extras[j].data, + afl->extras[i].len) == 0) { + + ck_free(afl->extras[j].data); + if (j + 1 < afl->extras_cnt) // not at the end of the list? + memmove((char *)&afl->extras[j], (char *)&afl->extras[j + 1], + (afl->extras_cnt - j - 1) * sizeof(struct extra_data)); + afl->extras_cnt--; + goto restart_dedup; // restart if several duplicates are in a row + + } + + } + + } + + if (afl->extras_cnt != orig_cnt) + afl->extras = afl_realloc((void **)&afl->extras, + afl->extras_cnt * sizeof(struct extra_data)); + +} + +/* Adds a new extra / dict entry. */ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { - u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX]; + u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX]; + u32 i, found = 0; + + for (i = 0; i < afl->extras_cnt; i++) { + + if (afl->extras[i].len == len) { + + if (memcmp(afl->extras[i].data, mem, len) == 0) return; + found = 1; + + } else { + + if (found) break; + + } + + } if (len > MAX_DICT_FILE) { - WARNF("Extra '%.*s' is very big (%s, limit is %s)", (int)len, mem, + WARNF("Extra '%.*s' is too big (%s, limit is %s)", (int)len, mem, stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len), stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE)); + return; } else if (len > 32) { @@ -405,8 +480,8 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { if (afl->extras_cnt == afl->max_det_extras + 1) { - OKF("More than %d tokens - will use them probabilistically.", - afl->max_det_extras); + WARNF("More than %d tokens - will use them probabilistically.", + afl->max_det_extras); } @@ -609,7 +684,7 @@ void load_auto(afl_state_t *afl) { } else { - OKF("No auto-generated dictionary tokens to reuse."); + ACTF("No auto-generated dictionary tokens to reuse."); } diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 102f04b9..713849a1 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -611,17 +611,17 @@ void read_foreign_testcases(afl_state_t *afl, int first) { /* Read all testcases from the input directory, then queue them for testing. Called at startup. */ -void read_testcases(afl_state_t *afl) { +void read_testcases(afl_state_t *afl, u8 *directory) { struct dirent **nl; - s32 nl_cnt; + s32 nl_cnt, subdirs = 1; u32 i; - u8 * fn1; - + u8 * fn1, *dir = directory; u8 val_buf[2][STRINGIFY_VAL_SIZE_MAX]; /* Auto-detect non-in-place resumption attempts. */ +if (dir == NULL) { fn1 = alloc_printf("%s/queue", afl->in_dir); if (!access(fn1, F_OK)) { @@ -632,16 +632,18 @@ void read_testcases(afl_state_t *afl) { ck_free(fn1); } + dir = afl->in_dir; +} - ACTF("Scanning '%s'...", afl->in_dir); + ACTF("Scanning '%s'...", dir); /* We use scandir() + alphasort() rather than readdir() because otherwise, the ordering of test cases would vary somewhat randomly and would be difficult to control. */ - nl_cnt = scandir(afl->in_dir, &nl, NULL, alphasort); + nl_cnt = scandir(dir, &nl, NULL, alphasort); - if (nl_cnt < 0) { + if (nl_cnt < 0 && directory == NULL) { if (errno == ENOENT || errno == ENOTDIR) { @@ -656,7 +658,7 @@ void read_testcases(afl_state_t *afl) { } - PFATAL("Unable to open '%s'", afl->in_dir); + PFATAL("Unable to open '%s'", dir); } @@ -674,19 +676,29 @@ void read_testcases(afl_state_t *afl) { u8 dfn[PATH_MAX]; snprintf(dfn, PATH_MAX, "%s/.state/deterministic_done/%s", afl->in_dir, nl[i]->d_name); - u8 *fn2 = alloc_printf("%s/%s", afl->in_dir, nl[i]->d_name); + u8 *fn2 = alloc_printf("%s/%s", dir, nl[i]->d_name); u8 passed_det = 0; - free(nl[i]); /* not tracked */ - if (lstat(fn2, &st) || access(fn2, R_OK)) { PFATAL("Unable to access '%s'", fn2); } - /* This also takes care of . and .. */ + /* obviously we want to skip "descending" into . and .. directories, + however it is a good idea to skip also directories that start with + a dot */ + if (subdirs && S_ISDIR(st.st_mode) && nl[i]->d_name[0] != '.') { + + free(nl[i]); /* not tracked */ + read_testcases(afl, fn2); + ck_free(fn2); + continue; + + } + + free(nl[i]); if (!S_ISREG(st.st_mode) || !st.st_size || strstr(fn2, "/README.txt")) { @@ -718,7 +730,7 @@ void read_testcases(afl_state_t *afl) { free(nl); /* not tracked */ - if (!afl->queued_paths) { + if (!afl->queued_paths && directory == NULL) { SAYF("\n" cLRD "[-] " cRST "Looks like there are no valid test cases in the input directory! The " @@ -985,6 +997,76 @@ void perform_dry_run(afl_state_t *afl) { } + /* Now we remove all entries from the queue that have a duplicate trace map */ + + q = afl->queue; + struct queue_entry *p, *prev = NULL; + int duplicates = 0; + +restart_outer_cull_loop: + + while (q) { + + if (q->cal_failed || !q->exec_cksum) continue; + + restart_inner_cull_loop: + + p = q->next; + + while (p) { + + if (!p->cal_failed && p->exec_cksum == q->exec_cksum) { + + duplicates = 1; + --afl->pending_not_fuzzed; + + // We do not remove any of the memory allocated because for + // splicing the data might still be interesting. + // We only decouple them from the linked list. + // This will result in some leaks at exit, but who cares. + + // we keep the shorter file + if (p->len >= q->len) { + + q->next = p->next; + goto restart_inner_cull_loop; + + } else { + + if (prev) + prev->next = q = p; + else + afl->queue = q = p; + goto restart_outer_cull_loop; + + } + + } + + p = p->next; + + } + + prev = q; + q = q->next; + + } + + if (duplicates) { + + afl->max_depth = 0; + q = afl->queue; + while (q) { + + if (q->depth > afl->max_depth) afl->max_depth = q->depth; + q = q->next; + + } + + afl->q_prev100 = afl->queue = afl->queue_top = afl->queue; + + } + OKF("All test cases processed."); } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index bf568c38..5737c1f5 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1707,20 +1707,8 @@ custom_mutator_stage: } while (tid == afl->current_entry && afl->queued_paths > 1); - target = afl->queue; - - while (tid >= 100) { - - target = target->next_100; - tid -= 100; - - } - - while (tid--) { - - target = target->next; - - } + afl->splicing_with = tid; + target = afl->queue_buf[tid]; /* Make sure that the target has a reasonable length. */ @@ -4518,20 +4506,7 @@ pacemaker_fuzzing: } while (tid == afl->current_entry); afl->splicing_with = tid; - target = afl->queue; - - while (tid >= 100) { - - target = target->next_100; - tid -= 100; - - } - - while (tid--) { - - target = target->next; - - } + target = afl->queue_buf[tid]; /* Make sure that the target has a reasonable length. */ diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index c6d8225f..db91813b 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -239,13 +239,6 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { afl->cycles_wo_finds = 0; - if (!(afl->queued_paths % 100)) { - - afl->q_prev100->next_100 = q; - afl->q_prev100 = q; - - } - struct queue_entry **queue_buf = afl_realloc( AFL_BUF_PARAM(queue), afl->queued_paths * sizeof(struct queue_entry *)); if (unlikely(!queue_buf)) { PFATAL("alloc"); } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index c12d5db5..bfaa22e8 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -119,8 +119,8 @@ static void usage(u8 *argv0, int more_help) { "etc.)\n" " -d - quick & dirty mode (skips deterministic steps)\n" " -n - fuzz without instrumentation (non-instrumented mode)\n" - " -x dict_file - optional fuzzer dictionary (see README.md, its really " - "good!)\n\n" + " -x dict_file - fuzzer dictionary (see README.md, specify up to 4 " + "times)\n\n" "Testing settings:\n" " -s seed - use a fixed seed for the RNG\n" @@ -243,11 +243,11 @@ static int stricmp(char const *a, char const *b) { int main(int argc, char **argv_orig, char **envp) { - s32 opt; + s32 opt, i; u64 prev_queued = 0; u32 sync_interval_cnt = 0, seek_to, show_help = 0, map_size = MAP_SIZE; - u8 * extras_dir = 0; - u8 mem_limit_given = 0, exit_1 = 0, debug = 0; + u8 * extras_dir[4]; + u8 mem_limit_given = 0, exit_1 = 0, debug = 0, extras_dir_cnt = 0; char **use_argv; struct timeval tv; @@ -450,8 +450,13 @@ int main(int argc, char **argv_orig, char **envp) { case 'x': /* dictionary */ - if (extras_dir) { FATAL("Multiple -x options not supported"); } - extras_dir = optarg; + if (extras_dir_cnt >= 4) { + + FATAL("More than four -x options are not supported"); + + } + + extras_dir[extras_dir_cnt++] = optarg; break; case 't': { /* timeout */ @@ -828,10 +833,6 @@ int main(int argc, char **argv_orig, char **envp) { "Eißfeldt, Andrea Fioraldi and Dominik Maier"); OKF("afl++ is open source, get it at " "https://github.com/AFLplusplus/AFLplusplus"); - OKF("Power schedules from github.com/mboehme/aflfast"); - OKF("Python Mutator and llvm_mode instrument file list from " - "github.com/choller/afl"); - OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL"); if (afl->sync_id && afl->is_main_node && afl->afl_env.afl_custom_mutator_only) { @@ -1139,7 +1140,15 @@ int main(int argc, char **argv_orig, char **envp) { pivot_inputs(afl); - if (extras_dir) { load_extras(afl, extras_dir); } + if (extras_dir_cnt) { + + for (i = 0; i < extras_dir_cnt; i++) + load_extras(afl, extras_dir[i]); + + dedup_extras(afl); + OKF("Loaded a total of %u extras.", afl->extras_cnt); + + } if (!afl->timeout_given) { find_timeout(afl); } -- cgit v1.2.3 From e30b2c6af6e369844c92c00a20ebdd53473a747c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 5 Sep 2020 13:18:28 +0200 Subject: final changes for pre-3.0 --- src/afl-fuzz-init.c | 3 ++- src/afl-fuzz-queue.c | 13 ++++++------- src/afl-fuzz-stats.c | 8 ++++---- src/afl-fuzz.c | 3 ++- 4 files changed, 14 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 713849a1..1351d274 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -626,6 +626,7 @@ if (dir == NULL) { if (!access(fn1, F_OK)) { afl->in_dir = fn1; + subdirs = 0; } else { @@ -1063,7 +1064,7 @@ restart_outer_cull_loop: } - afl->q_prev100 = afl->queue = afl->queue_top = afl->queue; + afl->queue = afl->queue_top = afl->queue; } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index db91813b..af52aa45 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -138,8 +138,7 @@ static u8 check_if_text(struct queue_entry *q) { } // non-overlong 2-byte - if (len - offset > 1 && - ((0xC2 <= buf[offset + 0] && buf[offset + 0] <= 0xDF) && + if (len - offset > 1 && ((0xC2 <= buf[offset + 0] && buf[offset + 0] <= 0xDF) && (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF))) { offset += 2; @@ -230,7 +229,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { } else { - afl->q_prev100 = afl->queue = afl->queue_top = q; + afl->queue = afl->queue_top = q; } @@ -274,15 +273,15 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { void destroy_queue(afl_state_t *afl) { - struct queue_entry *q = afl->queue, *n; + struct queue_entry *q; + u32 i; - while (q) { + for (i = 0; i < afl->queued_paths; i++) { - n = q->next; + q = afl->queue_buf[i]; ck_free(q->fname); ck_free(q->trace_mini); ck_free(q); - q = n; } diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 51eed14b..c60c65aa 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -982,10 +982,9 @@ void show_stats(afl_state_t *afl) { void show_init_stats(afl_state_t *afl) { struct queue_entry *q = afl->queue; - u32 min_bits = 0, max_bits = 0; + u32 min_bits = 0, max_bits = 0, max_len = 0, count = 0; u64 min_us = 0, max_us = 0; u64 avg_us = 0; - u32 max_len = 0; u8 val_bufs[4][STRINGIFY_VAL_SIZE_MAX]; #define IB(i) val_bufs[(i)], sizeof(val_bufs[(i)]) @@ -1006,6 +1005,7 @@ void show_init_stats(afl_state_t *afl) { if (q->len > max_len) { max_len = q->len; } + ++count; q = q->next; } @@ -1072,10 +1072,10 @@ void show_init_stats(afl_state_t *afl) { OKF("Here are some useful stats:\n\n" cGRA " Test case count : " cRST - "%u favored, %u variable, %u total\n" cGRA " Bitmap range : " cRST + "%u favored, %u variable, %u ignored, %u total\n" cGRA " Bitmap range : " cRST "%u to %u bits (average: %0.02f bits)\n" cGRA " Exec timing : " cRST "%s to %s us (average: %s us)\n", - afl->queued_favored, afl->queued_variable, afl->queued_paths, min_bits, + afl->queued_favored, afl->queued_variable, afl->queued_paths - count, afl->queued_paths, min_bits, max_bits, ((double)afl->total_bitmap_size) / (afl->total_bitmap_entries ? afl->total_bitmap_entries : 1), diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index bfaa22e8..73ca6aaa 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1133,8 +1133,9 @@ int main(int argc, char **argv_orig, char **envp) { setup_cmdline_file(afl, argv + optind); - read_testcases(afl); + read_testcases(afl, NULL); // read_foreign_testcases(afl, 1); for the moment dont do this + OKF("Loaded a total of %u seeds.", afl->queued_paths); load_auto(afl); -- cgit v1.2.3 From 2f90f2faba92c0ef5e081ff74b54fb07eb1faaa9 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 5 Sep 2020 13:19:19 +0200 Subject: code-format --- src/afl-fuzz-init.c | 23 +++++++++++++---------- src/afl-fuzz-queue.c | 3 ++- src/afl-fuzz-stats.c | 16 +++++++++------- 3 files changed, 24 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 1351d274..c834e5db 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -617,24 +617,27 @@ void read_testcases(afl_state_t *afl, u8 *directory) { s32 nl_cnt, subdirs = 1; u32 i; u8 * fn1, *dir = directory; - u8 val_buf[2][STRINGIFY_VAL_SIZE_MAX]; + u8 val_buf[2][STRINGIFY_VAL_SIZE_MAX]; /* Auto-detect non-in-place resumption attempts. */ -if (dir == NULL) { - fn1 = alloc_printf("%s/queue", afl->in_dir); - if (!access(fn1, F_OK)) { + if (dir == NULL) { - afl->in_dir = fn1; - subdirs = 0; + fn1 = alloc_printf("%s/queue", afl->in_dir); + if (!access(fn1, F_OK)) { - } else { + afl->in_dir = fn1; + subdirs = 0; + + } else { - ck_free(fn1); + ck_free(fn1); + + } + + dir = afl->in_dir; } - dir = afl->in_dir; -} ACTF("Scanning '%s'...", dir); diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index af52aa45..8c7bfc55 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -138,7 +138,8 @@ static u8 check_if_text(struct queue_entry *q) { } // non-overlong 2-byte - if (len - offset > 1 && ((0xC2 <= buf[offset + 0] && buf[offset + 0] <= 0xDF) && + if (len - offset > 1 && + ((0xC2 <= buf[offset + 0] && buf[offset + 0] <= 0xDF) && (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF))) { offset += 2; diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index c60c65aa..dfc0cd97 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -35,12 +35,12 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { u8 fn[PATH_MAX]; snprintf(fn, PATH_MAX, "%s/fuzzer_setup", afl->out_dir); FILE *f = create_ffile(fn); - u32 i; + u32 i; fprintf(f, "# environment variables:\n"); - u32 s_afl_env = (u32) - sizeof(afl_environment_variables) / sizeof(afl_environment_variables[0]) - - 1U; + u32 s_afl_env = (u32)sizeof(afl_environment_variables) / + sizeof(afl_environment_variables[0]) - + 1U; for (i = 0; i < s_afl_env; ++i) { @@ -75,6 +75,7 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { } } + fprintf(f, "\n"); fclose(f); @@ -1072,11 +1073,12 @@ void show_init_stats(afl_state_t *afl) { OKF("Here are some useful stats:\n\n" cGRA " Test case count : " cRST - "%u favored, %u variable, %u ignored, %u total\n" cGRA " Bitmap range : " cRST + "%u favored, %u variable, %u ignored, %u total\n" cGRA + " Bitmap range : " cRST "%u to %u bits (average: %0.02f bits)\n" cGRA " Exec timing : " cRST "%s to %s us (average: %s us)\n", - afl->queued_favored, afl->queued_variable, afl->queued_paths - count, afl->queued_paths, min_bits, - max_bits, + afl->queued_favored, afl->queued_variable, afl->queued_paths - count, + afl->queued_paths, min_bits, max_bits, ((double)afl->total_bitmap_size) / (afl->total_bitmap_entries ? afl->total_bitmap_entries : 1), stringify_int(IB(0), min_us), stringify_int(IB(1), max_us), -- cgit v1.2.3 From ded4d093ff59b4459b04aaae9b3b7bbcdaadcdef Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 5 Sep 2020 16:16:56 +0200 Subject: skip crashes but keep for splices --- src/afl-fuzz-init.c | 35 +++++++++++++++++++++++++++++------ src/afl-fuzz.c | 3 +++ 2 files changed, 32 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index c834e5db..a5ebbcd8 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -713,11 +713,9 @@ void read_testcases(afl_state_t *afl, u8 *directory) { if (st.st_size > MAX_FILE) { - WARNF("Test case '%s' is too big (%s, limit is %s), skipping", fn2, + WARNF("Test case '%s' is too big (%s, limit is %s), partial reading", fn2, stringify_mem_size(val_buf[0], sizeof(val_buf[0]), st.st_size), stringify_mem_size(val_buf[1], sizeof(val_buf[1]), MAX_FILE)); - ck_free(fn2); - continue; } @@ -728,7 +726,8 @@ void read_testcases(afl_state_t *afl, u8 *directory) { if (!access(dfn, F_OK)) { passed_det = 1; } - add_to_queue(afl, fn2, st.st_size, passed_det); + add_to_queue(afl, fn2, st.st_size >= MAX_FILE ? MAX_FILE : st.st_size, + passed_det); } @@ -947,7 +946,31 @@ void perform_dry_run(afl_state_t *afl) { #undef MSG_ULIMIT_USAGE #undef MSG_FORK_ON_APPLE - FATAL("Test case '%s' results in a crash", fn); + WARNF("Test case '%s' results in a crash, skipping", fn); + + /* Remove from fuzzing queue but keep for splicing */ + + struct queue_entry *p = afl->queue; + while (p && p->next != q) + p = p->next; + + if (p) + p->next = q->next; + else + afl->queue = q->next; + + --afl->pending_not_fuzzed; + + afl->max_depth = 0; + p = afl->queue; + while (p) { + + if (p->depth > afl->max_depth) afl->max_depth = p->depth; + p = p->next; + + } + + break; case FSRV_RUN_ERROR: @@ -1067,7 +1090,7 @@ restart_outer_cull_loop: } - afl->queue = afl->queue_top = afl->queue; + afl->queue_top = afl->queue; } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 73ca6aaa..a8816cb3 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1282,6 +1282,9 @@ int main(int argc, char **argv_orig, char **envp) { cull_queue(afl); + if (!afl->pending_not_fuzzed) + FATAL("We need at least on valid input seed that does not crash!"); + show_init_stats(afl); seek_to = find_start_position(afl); -- cgit v1.2.3 From 163e5ffd10936e6e119f643495129ab05fa3e5ec Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 5 Sep 2020 17:40:39 +0200 Subject: -p seek is now the default --- src/afl-fuzz-state.c | 2 +- src/afl-fuzz.c | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 577fc34f..4e817843 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -87,7 +87,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->w_end = 0.3; afl->g_max = 5000; afl->period_pilot_tmp = 5000.0; - afl->schedule = EXPLORE; /* Power schedule (default: EXPLORE)*/ + afl->schedule = SEEK; /* Power schedule (default: SEEK) */ afl->havoc_max_mult = HAVOC_MAX_MULT; afl->clear_screen = 1; /* Window resized? */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index a8816cb3..5b96ef45 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -89,11 +89,10 @@ static void usage(u8 *argv0, int more_help) { " -o dir - output directory for fuzzer findings\n\n" "Execution control settings:\n" - " -p schedule - power schedules compute a seed's performance score. " - "\n" - " see docs/power_schedules.md\n" + " -p schedule - power schedules compute a seed's performance score:\n" + " -- see docs/power_schedules.md\n" " -f file - location read by the fuzzed program (default: stdin " "or @@)\n" " -t msec - timeout for each run (auto-scaled, 50-%d ms)\n" @@ -349,15 +348,15 @@ int main(int argc, char **argv_orig, char **envp) { afl->schedule = RARE; - } else if (!stricmp(optarg, "seek")) { + } else if (!stricmp(optarg, "explore") || !stricmp(optarg, "afl")) { - afl->schedule = SEEK; + afl->schedule = EXPLORE; - } else if (!stricmp(optarg, "explore") || !stricmp(optarg, "default") || + } else if (!stricmp(optarg, "seek") || !stricmp(optarg, "default") || - !stricmp(optarg, "normal") || !stricmp(optarg, "afl")) { + !stricmp(optarg, "normal")) { - afl->schedule = EXPLORE; + afl->schedule = SEEK; } else { -- cgit v1.2.3 From 8ec41b2585390c54256dd823e1beafd6246d9976 Mon Sep 17 00:00:00 2001 From: aflpp Date: Sun, 6 Sep 2020 11:40:41 +0200 Subject: fix various warnings --- src/afl-cc.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index e11ce40a..ddda3845 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1153,9 +1153,6 @@ int main(int argc, char **argv, char **envp) { if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) { - char *fp; - fp = realpath(argv[0], NULL); - printf("afl-cc" VERSION " by Michal Zalewski, Laszlo Szekeres, Marc Heuse\n"); @@ -1302,8 +1299,7 @@ int main(int argc, char **argv, char **envp) { " AFL_USE_ASAN: activate address sanitizer\n" " AFL_USE_CFISAN: activate control flow sanitizer\n" " AFL_USE_MSAN: activate memory sanitizer\n" - " AFL_USE_UBSAN: activate undefined behaviour sanitizer\n", - BIN_PATH, BIN_PATH); + " AFL_USE_UBSAN: activate undefined behaviour sanitizer\n"); SAYF( "\nLLVM/LTO/afl-clang-fast/afl-clang-lto specific environment " -- cgit v1.2.3 From 7bcbfd48e54eba5a99d05b04f4f3d6bea29cde80 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 6 Sep 2020 15:12:23 +0200 Subject: update ideas --- src/README.md | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/README.md b/src/README.md index 6da534c3..35af6ab9 100644 --- a/src/README.md +++ b/src/README.md @@ -2,23 +2,28 @@ Quick explanation about the files here: -- `afl-analyze.c` - afl-analyze binary tool +- `afl-analyze.c` - afl-analyze binary tool - `afl-as.c` - afl-as binary tool -- `afl-gotcpu.c` - afl-gotcpu binary tool -- `afl-showmap.c` - afl-showmap binary tool -- `afl-tmin.c` - afl-tmin binary tool -- `afl-fuzz.c` - afl-fuzz binary tool (just main() and usage()) +- `afl-cc.c` - afl-cc binary tool +- `afl-common.c` - common functions, used by afl-analyze, afl-fuzz, afl-showmap and afl-tmin +- `afl-forkserver.c` - forkserver implementation, used by afl-fuzz afl-showmap, afl-tmin - `afl-fuzz-bitmap.c` - afl-fuzz bitmap handling +- `afl-fuzz.c` - afl-fuzz binary tool (just main() and usage()) +- `afl-fuzz-cmplog.c` - afl-fuzz cmplog functions - `afl-fuzz-extras.c` - afl-fuzz the *extra* function calls -- `afl-fuzz-state.c` - afl-fuzz state and globals -- `afl-fuzz-init.c` - afl-fuzz initialization -- `afl-fuzz-misc.c` - afl-fuzz misc functions -- `afl-fuzz-one.c` - afl-fuzz fuzzer_one big loop, this is where the mutation is happening +- `afl-fuzz-init.c` - afl-fuzz initialization +- `afl-fuzz-misc.c` - afl-fuzz misc functions +- `afl-fuzz-mutators.c` - afl-fuzz custom mutator and python support +- `afl-fuzz-one.c` - afl-fuzz fuzzer_one big loop, this is where the mutation is happening +- `afl-fuzz-performance.c` - hash64 and rand functions - `afl-fuzz-python.c` - afl-fuzz the python mutator extension - `afl-fuzz-queue.c` - afl-fuzz handling the queue -- `afl-fuzz-run.c` - afl-fuzz running the target +- `afl-fuzz-redqueen.c` - afl-fuzz redqueen implemention +- `afl-fuzz-run.c` - afl-fuzz running the target +- `afl-fuzz-state.c` - afl-fuzz state and globals - `afl-fuzz-stats.c` - afl-fuzz writing the statistics file -- `afl-gcc.c` - afl-gcc binary tool (deprecated) -- `afl-common.c` - common functions, used by afl-analyze, afl-fuzz, afl-showmap and afl-tmin -- `afl-forkserver.c` - forkserver implementation, used by afl-fuzz and afl-tmin -afl-sharedmem.c - sharedmem implementation, used by afl-fuzz and afl-tmin +- `afl-gotcpu.c` - afl-gotcpu binary tool +- `afl-ld-lto.c` - LTO linker helper +- `afl-sharedmem.c` - sharedmem implementation, used by afl-fuzz, afl-showmap, afl-tmin +- `afl-showmap.c` - afl-showmap binary tool +- `afl-tmin.c` - afl-tmin binary tool -- cgit v1.2.3 From 6404abd7d609350ffd6c6f221cbf56e60b2ef030 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 7 Sep 2020 17:30:28 +0200 Subject: bugfix for fixed seeds --- src/afl-fuzz-queue.c | 2 +- src/afl-fuzz-stats.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 8c7bfc55..336b7f4f 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -502,7 +502,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { // Longer execution time means longer work on the input, the deeper in // coverage, the better the fuzzing, right? -mh - if (afl->schedule >= RARE && likely(!afl->fixed_seed)) { + if (likely(afl->schedule < RARE) && likely(!afl->fixed_seed)) { if (q->exec_us * 0.1 > avg_exec_us) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index dfc0cd97..1d5b169d 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -1022,7 +1022,11 @@ void show_init_stats(afl_state_t *afl) { /* Let's keep things moving with slow binaries. */ - if (avg_us > 50000) { + if (unlikely(afl->fixed_seed)) { + + afl->havoc_div = 1; + + } else if (avg_us > 50000) { afl->havoc_div = 10; /* 0-19 execs/sec */ @@ -1093,7 +1097,11 @@ void show_init_stats(afl_state_t *afl) { random scheduler jitter is less likely to have any impact, and because our patience is wearing thin =) */ - if (avg_us > 50000) { + if (unlikely(afl->fixed_seed)) { + + afl->fsrv.exec_tmout = avg_us * 5 / 1000; + + } else if (avg_us > 50000) { afl->fsrv.exec_tmout = avg_us * 2 / 1000; -- cgit v1.2.3 From 374e068f97e07831f30b6253157560565240fd52 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 8 Sep 2020 11:37:09 +0200 Subject: set correct error code when -V --- src/afl-forkserver.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 58932bc4..c8056b9e 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1043,7 +1043,12 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, } - if (fsrv->child_pid <= 0) { FATAL("Fork server is misbehaving (OOM?)"); } + if (fsrv->child_pid <= 0) { + + if (*stop_soon_p) { return 0; } + FATAL("Fork server is misbehaving (OOM?)"); + + } exec_ms = read_s32_timed(fsrv->fsrv_st_fd, &fsrv->child_status, timeout, stop_soon_p); -- cgit v1.2.3 From 9544b3dbf22f1007f7d3f77593ec746a0345a587 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Mon, 7 Sep 2020 12:35:31 -0300 Subject: rewrite gcc plugin When we started using AFL, it did not have an integrated GCC plugin. There was one proposed by Austin Seipp, but for various reasons we ended up using some of its infrastructure (runtime and wrapper), but writing the GCC plugin proper from scratch. With AFL++'s renewed interest in a GCC plugin, we rebased ours, with some features that are or were missing in the one that was integrated: * efficient, fully-functional inline and out-of-line instrumentation Inline instrumentation was work in progress in the original plugin. Controlled by AFL_GCC_OUT_OF_LINE. * reproducible instrumentation Obey -frandom-seed for pseudorandom number generation. * licensing clarity and strict compliance GPLv3+ for the plugin, that uses GCC internals; add a copy of the license, as required. * allow/deny list support Copied and adjusted from the LLVM plugin implementation. * neverZero support Not as compact as the asm-wrapper version, but likely more efficient. Both are quite thread-unsafe, with different caveats. Controlled with AFL_GCC_SKIP_NEVERZERO. --- src/afl-cc.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index ddda3845..78245d4b 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1335,6 +1335,12 @@ int main(int argc, char **argv, char **envp) { AFL_REAL_LD, AFL_CLANG_FLTO); #endif + SAYF( + "\nGCC Plugin-specific environment variables:\n" + "AFL_GCC_OUT_OF_LINE: disable inlined instrumentation\n" + "AFL_GCC_SKIP_NEVERZERO: do not skip zero on trace counters\n" + "AFL_GCC_INSTRUMENT_FILE: enable selective instrumentation by " + "filename\n"); } SAYF( -- cgit v1.2.3 From c091340a85694c5de1125a93366f2733959487f5 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 8 Sep 2020 16:15:31 +0200 Subject: new gcc_plugin integration --- src/afl-cc.c | 76 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 38 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 78245d4b..47a33cd0 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1196,7 +1196,7 @@ int main(int argc, char **argv, char **envp) { " - NGRAM-{2-16}\n" " [GCC_PLUGIN] gcc plugin: %s%s\n" " CLASSIC DEFAULT no yes yes no no no " - " simple\n" + " yes\n" " [GCC] simple gcc: %s%s\n" " CLASSIC DEFAULT no no no no no no " " no\n\n", @@ -1270,8 +1270,29 @@ int main(int argc, char **argv, char **envp) { " AFL_CXX: path to the C++ compiler to use\n" " AFL_DEBUG: enable developer debugging output\n" " AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" - " AFL_HARDEN: adds code hardening to catch memory bugs\n" + " AFL_NO_BUILTIN: no builtins for string compare functions (for " + "libtokencap.so)\n" + " AFL_PATH: path to instrumenting pass and runtime " + "(afl-compiler-rt.*o)\n" " AFL_INST_RATIO: percentage of branches to instrument\n" + " AFL_QUIET: suppress verbose output\n" + " AFL_HARDEN: adds code hardening to catch memory bugs\n" + " AFL_USE_ASAN: activate address sanitizer\n" + " AFL_USE_CFISAN: activate control flow sanitizer\n" + " AFL_USE_MSAN: activate memory sanitizer\n" + " AFL_USE_UBSAN: activate undefined behaviour sanitizer\n"); + + if (have_gcc_plugin) + SAYF( + "\nGCC Plugin-specific environment variables:\n" + " AFL_GCC_OUT_OF_LINE: disable inlined instrumentation\n" + " AFL_GCC_SKIP_NEVERZERO: do not skip zero on trace counters\n" + " AFL_GCC_INSTRUMENT_FILE: enable selective instrumentation by filename\n"); + + if (have_llvm) + SAYF( + "\nLLVM/LTO/afl-clang-fast/afl-clang-lto specific environment " + "variables:\n" #if LLVM_MAJOR < 9 " AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n" #else @@ -1288,25 +1309,13 @@ int main(int argc, char **argv, char **envp) { "functions\n" " AFL_LLVM_INSTRUMENT_ALLOW/AFL_LLVM_INSTRUMENT_DENY: enable " "instrument allow/\n" - " deny listing (selective instrumentation)\n" - " AFL_NO_BUILTIN: no builtins for string compare functions (for " - "libtokencap.so)\n" - " AFL_PATH: path to instrumenting pass and runtime " - "(afl-compiler-rt.*o)\n" - " AFL_LLVM_DOCUMENT_IDS: document edge IDs given to which function " - "(LTO only)\n" - " AFL_QUIET: suppress verbose output\n" - " AFL_USE_ASAN: activate address sanitizer\n" - " AFL_USE_CFISAN: activate control flow sanitizer\n" - " AFL_USE_MSAN: activate memory sanitizer\n" - " AFL_USE_UBSAN: activate undefined behaviour sanitizer\n"); + " deny listing (selective instrumentation)\n"); + if (have_llvm) SAYF( - "\nLLVM/LTO/afl-clang-fast/afl-clang-lto specific environment " - "variables:\n" " AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen mutator)\n" - " AFL_LLVM_INSTRUMENT: set instrumentation mode: CLASSIC, INSTRIM, " - "PCGUARD, LTO, CTX, NGRAM-2 ... NGRAM-16\n" + " AFL_LLVM_INSTRUMENT: set instrumentation mode:\n" + " CLASSIC, INSTRIM, PCGUARD, LTO, CTX, NGRAM-2 ... NGRAM-16\n" " You can also use the old environment variables instead:\n" " AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n" " AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n" @@ -1315,36 +1324,27 @@ int main(int argc, char **argv, char **envp) { " AFL_LLVM_CTX: use context sensitive coverage (for CLASSIC and " "INSTRIM)\n" " AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage (for " - "CLASSIC and INSTRIM)\n"); + "CLASSIC & INSTRIM)\n"); #ifdef AFL_CLANG_FLTO - SAYF( + if (have_lto) + SAYF( "\nLTO/afl-clang-lto specific environment variables:\n" - "AFL_LLVM_MAP_ADDR: use a fixed coverage map address (speed), e.g. " + " AFL_LLVM_MAP_ADDR: use a fixed coverage map address (speed), e.g. " "0x10000\n" - "AFL_LLVM_DOCUMENT_IDS: write all edge IDs and the corresponding " - "functions they are in into this file\n" - "AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a " + " AFL_LLVM_DOCUMENT_IDS: write all edge IDs and the corresponding functions\n" + " into this file\n" + " AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a " "global var\n" - "AFL_LLVM_LTO_STARTID: from which ID to start counting from for a " + " AFL_LLVM_LTO_STARTID: from which ID to start counting from for a " "bb\n" - "AFL_REAL_LD: use this lld linker instead of the compiled in path\n" - "\nafl-clang-lto was built with linker target \"%s\" and LTO flags " - "\"%s\"\n" - "If anything fails - be sure to read README.lto.md!\n", - AFL_REAL_LD, AFL_CLANG_FLTO); + " AFL_REAL_LD: use this lld linker instead of the compiled in path\n" + "If anything fails - be sure to read README.lto.md!\n"); #endif - - SAYF( - "\nGCC Plugin-specific environment variables:\n" - "AFL_GCC_OUT_OF_LINE: disable inlined instrumentation\n" - "AFL_GCC_SKIP_NEVERZERO: do not skip zero on trace counters\n" - "AFL_GCC_INSTRUMENT_FILE: enable selective instrumentation by " - "filename\n"); } SAYF( - "For any information on the available instrumentations and options " + "\nFor any information on the available instrumentations and options " "please \n" "consult the README.md, especially section 3.1 about instrumenting " "targets.\n\n"); -- cgit v1.2.3 From 2802245da77062cdadb7d4ceb09d3d083761cf56 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 8 Sep 2020 17:15:32 +0200 Subject: update instrumenation/README.instrument_file.md for gcc_plugin --- src/afl-fuzz-init.c | 3 +- src/afl-fuzz-mutators.c | 4 +- src/afl-fuzz.c | 98 ++++++++++++++++++++++++------------------------- 3 files changed, 52 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index a5ebbcd8..29c8c6fa 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1775,7 +1775,6 @@ int check_main_node_exists(afl_state_t *afl) { void setup_dirs_fds(afl_state_t *afl) { u8 *tmp; - s32 fd; ACTF("Setting up output directories..."); @@ -1901,7 +1900,7 @@ void setup_dirs_fds(afl_state_t *afl) { /* Gnuplot output file. */ tmp = alloc_printf("%s/plot_data", afl->out_dir); - fd = open(tmp, O_WRONLY | O_CREAT | O_EXCL, 0600); + int fd = open(tmp, O_WRONLY | O_CREAT | O_EXCL, 0600); if (fd < 0) { PFATAL("Unable to create '%s'", tmp); } ck_free(tmp); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index d24b7db9..c4d7233c 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -93,9 +93,9 @@ void setup_custom_mutators(afl_state_t *afl) { } - struct custom_mutator *mutator = load_custom_mutator_py(afl, module_name); + struct custom_mutator *m = load_custom_mutator_py(afl, module_name); afl->custom_mutators_count++; - list_append(&afl->custom_mutator_list, mutator); + list_append(&afl->custom_mutator_list, m); } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 5b96ef45..9196d78b 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -698,7 +698,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->swarm_now = 0; if (afl->limit_time_puppet == 0) { afl->key_puppet = 1; } - int i; + int j; int tmp_swarm = 0; if (afl->g_now > afl->g_max) { afl->g_now = 0; } @@ -711,70 +711,70 @@ int main(int argc, char **argv_orig, char **envp) { double total_puppet_temp = 0.0; afl->swarm_fitness[tmp_swarm] = 0.0; - for (i = 0; i < operator_num; ++i) { + for (j = 0; j < operator_num; ++j) { - afl->stage_finds_puppet[tmp_swarm][i] = 0; - afl->probability_now[tmp_swarm][i] = 0.0; - afl->x_now[tmp_swarm][i] = + afl->stage_finds_puppet[tmp_swarm][j] = 0; + afl->probability_now[tmp_swarm][j] = 0.0; + afl->x_now[tmp_swarm][j] = ((double)(random() % 7000) * 0.0001 + 0.1); - total_puppet_temp += afl->x_now[tmp_swarm][i]; - afl->v_now[tmp_swarm][i] = 0.1; - afl->L_best[tmp_swarm][i] = 0.5; - afl->G_best[i] = 0.5; - afl->eff_best[tmp_swarm][i] = 0.0; + total_puppet_temp += afl->x_now[tmp_swarm][j]; + afl->v_now[tmp_swarm][j] = 0.1; + afl->L_best[tmp_swarm][j] = 0.5; + afl->G_best[j] = 0.5; + afl->eff_best[tmp_swarm][j] = 0.0; } - for (i = 0; i < operator_num; ++i) { + for (j = 0; j < operator_num; ++j) { - afl->stage_cycles_puppet_v2[tmp_swarm][i] = - afl->stage_cycles_puppet[tmp_swarm][i]; - afl->stage_finds_puppet_v2[tmp_swarm][i] = - afl->stage_finds_puppet[tmp_swarm][i]; - afl->x_now[tmp_swarm][i] = - afl->x_now[tmp_swarm][i] / total_puppet_temp; + afl->stage_cycles_puppet_v2[tmp_swarm][j] = + afl->stage_cycles_puppet[tmp_swarm][j]; + afl->stage_finds_puppet_v2[tmp_swarm][j] = + afl->stage_finds_puppet[tmp_swarm][j]; + afl->x_now[tmp_swarm][j] = + afl->x_now[tmp_swarm][j] / total_puppet_temp; } double x_temp = 0.0; - for (i = 0; i < operator_num; ++i) { + for (j = 0; j < operator_num; ++j) { - afl->probability_now[tmp_swarm][i] = 0.0; - afl->v_now[tmp_swarm][i] = - afl->w_now * afl->v_now[tmp_swarm][i] + + afl->probability_now[tmp_swarm][j] = 0.0; + afl->v_now[tmp_swarm][j] = + afl->w_now * afl->v_now[tmp_swarm][j] + RAND_C * - (afl->L_best[tmp_swarm][i] - afl->x_now[tmp_swarm][i]) + - RAND_C * (afl->G_best[i] - afl->x_now[tmp_swarm][i]); + (afl->L_best[tmp_swarm][j] - afl->x_now[tmp_swarm][j]) + + RAND_C * (afl->G_best[j] - afl->x_now[tmp_swarm][j]); - afl->x_now[tmp_swarm][i] += afl->v_now[tmp_swarm][i]; + afl->x_now[tmp_swarm][j] += afl->v_now[tmp_swarm][j]; - if (afl->x_now[tmp_swarm][i] > v_max) { + if (afl->x_now[tmp_swarm][j] > v_max) { - afl->x_now[tmp_swarm][i] = v_max; + afl->x_now[tmp_swarm][j] = v_max; - } else if (afl->x_now[tmp_swarm][i] < v_min) { + } else if (afl->x_now[tmp_swarm][j] < v_min) { - afl->x_now[tmp_swarm][i] = v_min; + afl->x_now[tmp_swarm][j] = v_min; } - x_temp += afl->x_now[tmp_swarm][i]; + x_temp += afl->x_now[tmp_swarm][j]; } - for (i = 0; i < operator_num; ++i) { + for (j = 0; j < operator_num; ++j) { - afl->x_now[tmp_swarm][i] = afl->x_now[tmp_swarm][i] / x_temp; - if (likely(i != 0)) { + afl->x_now[tmp_swarm][j] = afl->x_now[tmp_swarm][j] / x_temp; + if (likely(j != 0)) { - afl->probability_now[tmp_swarm][i] = - afl->probability_now[tmp_swarm][i - 1] + - afl->x_now[tmp_swarm][i]; + afl->probability_now[tmp_swarm][j] = + afl->probability_now[tmp_swarm][j - 1] + + afl->x_now[tmp_swarm][j]; } else { - afl->probability_now[tmp_swarm][i] = afl->x_now[tmp_swarm][i]; + afl->probability_now[tmp_swarm][j] = afl->x_now[tmp_swarm][j]; } @@ -789,13 +789,13 @@ int main(int argc, char **argv_orig, char **envp) { } - for (i = 0; i < operator_num; ++i) { + for (j = 0; j < operator_num; ++j) { - afl->core_operator_finds_puppet[i] = 0; - afl->core_operator_finds_puppet_v2[i] = 0; - afl->core_operator_cycles_puppet[i] = 0; - afl->core_operator_cycles_puppet_v2[i] = 0; - afl->core_operator_cycles_puppet_v3[i] = 0; + afl->core_operator_finds_puppet[j] = 0; + afl->core_operator_finds_puppet_v2[j] = 0; + afl->core_operator_cycles_puppet[j] = 0; + afl->core_operator_cycles_puppet_v2[j] = 0; + afl->core_operator_cycles_puppet_v3[j] = 0; } @@ -1010,10 +1010,10 @@ int main(int argc, char **argv_orig, char **envp) { u8 *afl_preload = getenv("AFL_PRELOAD"); u8 *buf; - s32 i, afl_preload_size = strlen(afl_preload); - for (i = 0; i < afl_preload_size; ++i) { + s32 j, afl_preload_size = strlen(afl_preload); + for (j = 0; j < afl_preload_size; ++j) { - if (afl_preload[i] == ',') { + if (afl_preload[j] == ',') { PFATAL( "Comma (',') is not allowed in AFL_PRELOAD when -Q is " @@ -1188,10 +1188,10 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->fsrv.out_file) { - u32 i = optind + 1; - while (argv[i]) { + u32 j = optind + 1; + while (argv[j]) { - u8 *aa_loc = strstr(argv[i], "@@"); + u8 *aa_loc = strstr(argv[j], "@@"); if (aa_loc && !afl->fsrv.out_file) { @@ -1214,7 +1214,7 @@ int main(int argc, char **argv_orig, char **envp) { } - ++i; + ++j; } -- cgit v1.2.3 From ab744abc4b3c90bee355807e7b6e40ba86f23e74 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 8 Sep 2020 17:54:01 +0200 Subject: code-format --- src/afl-cc.c | 105 +++++++++++++++++++++++++++------------------------ src/afl-forkserver.c | 6 +-- 2 files changed, 59 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 47a33cd0..6bee8b38 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1282,65 +1282,72 @@ int main(int argc, char **argv, char **envp) { " AFL_USE_MSAN: activate memory sanitizer\n" " AFL_USE_UBSAN: activate undefined behaviour sanitizer\n"); - if (have_gcc_plugin) - SAYF( - "\nGCC Plugin-specific environment variables:\n" - " AFL_GCC_OUT_OF_LINE: disable inlined instrumentation\n" - " AFL_GCC_SKIP_NEVERZERO: do not skip zero on trace counters\n" - " AFL_GCC_INSTRUMENT_FILE: enable selective instrumentation by filename\n"); - + if (have_gcc_plugin) + SAYF( + "\nGCC Plugin-specific environment variables:\n" + " AFL_GCC_OUT_OF_LINE: disable inlined instrumentation\n" + " AFL_GCC_SKIP_NEVERZERO: do not skip zero on trace counters\n" + " AFL_GCC_INSTRUMENT_FILE: enable selective instrumentation by " + "filename\n"); + if (have_llvm) SAYF( - "\nLLVM/LTO/afl-clang-fast/afl-clang-lto specific environment " - "variables:\n" + "\nLLVM/LTO/afl-clang-fast/afl-clang-lto specific environment " + "variables:\n" #if LLVM_MAJOR < 9 - " AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n" + " AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n" #else - " AFL_LLVM_SKIP_NEVERZERO: do not skip zero on trace counters\n" + " AFL_LLVM_SKIP_NEVERZERO: do not skip zero on trace counters\n" #endif - " AFL_LLVM_DICT2FILE: generate an afl dictionary based on found " - "comparisons\n" - " AFL_LLVM_LAF_ALL: enables all LAF splits/transforms\n" - " AFL_LLVM_LAF_SPLIT_COMPARES: enable cascaded comparisons\n" - " AFL_LLVM_LAF_SPLIT_COMPARES_BITW: size limit (default 8)\n" - " AFL_LLVM_LAF_SPLIT_SWITCHES: cascaded comparisons on switches\n" - " AFL_LLVM_LAF_SPLIT_FLOATS: cascaded comparisons on floats\n" - " AFL_LLVM_LAF_TRANSFORM_COMPARES: cascade comparisons for string " - "functions\n" - " AFL_LLVM_INSTRUMENT_ALLOW/AFL_LLVM_INSTRUMENT_DENY: enable " - "instrument allow/\n" - " deny listing (selective instrumentation)\n"); + " AFL_LLVM_DICT2FILE: generate an afl dictionary based on found " + "comparisons\n" + " AFL_LLVM_LAF_ALL: enables all LAF splits/transforms\n" + " AFL_LLVM_LAF_SPLIT_COMPARES: enable cascaded comparisons\n" + " AFL_LLVM_LAF_SPLIT_COMPARES_BITW: size limit (default 8)\n" + " AFL_LLVM_LAF_SPLIT_SWITCHES: cascaded comparisons on switches\n" + " AFL_LLVM_LAF_SPLIT_FLOATS: cascaded comparisons on floats\n" + " AFL_LLVM_LAF_TRANSFORM_COMPARES: cascade comparisons for string " + "functions\n" + " AFL_LLVM_INSTRUMENT_ALLOW/AFL_LLVM_INSTRUMENT_DENY: enable " + "instrument allow/\n" + " deny listing (selective instrumentation)\n"); if (have_llvm) - SAYF( - " AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen mutator)\n" - " AFL_LLVM_INSTRUMENT: set instrumentation mode:\n" - " CLASSIC, INSTRIM, PCGUARD, LTO, CTX, NGRAM-2 ... NGRAM-16\n" - " You can also use the old environment variables instead:\n" - " AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n" - " AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n" - " AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed " - "(option to INSTRIM)\n" - " AFL_LLVM_CTX: use context sensitive coverage (for CLASSIC and " - "INSTRIM)\n" - " AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage (for " - "CLASSIC & INSTRIM)\n"); + SAYF( + " AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen " + "mutator)\n" + " AFL_LLVM_INSTRUMENT: set instrumentation mode:\n" + " CLASSIC, INSTRIM, PCGUARD, LTO, CTX, NGRAM-2 ... NGRAM-16\n" + " You can also use the old environment variables instead:\n" + " AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n" + " AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n" + " AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed " + "(option to INSTRIM)\n" + " AFL_LLVM_CTX: use context sensitive coverage (for CLASSIC and " + "INSTRIM)\n" + " AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage (for " + "CLASSIC & INSTRIM)\n"); #ifdef AFL_CLANG_FLTO - if (have_lto) - SAYF( - "\nLTO/afl-clang-lto specific environment variables:\n" - " AFL_LLVM_MAP_ADDR: use a fixed coverage map address (speed), e.g. " - "0x10000\n" - " AFL_LLVM_DOCUMENT_IDS: write all edge IDs and the corresponding functions\n" - " into this file\n" - " AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a " - "global var\n" - " AFL_LLVM_LTO_STARTID: from which ID to start counting from for a " - "bb\n" - " AFL_REAL_LD: use this lld linker instead of the compiled in path\n" - "If anything fails - be sure to read README.lto.md!\n"); + if (have_lto) + SAYF( + "\nLTO/afl-clang-lto specific environment variables:\n" + " AFL_LLVM_MAP_ADDR: use a fixed coverage map address (speed), " + "e.g. " + "0x10000\n" + " AFL_LLVM_DOCUMENT_IDS: write all edge IDs and the corresponding " + "functions\n" + " into this file\n" + " AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a " + "global var\n" + " AFL_LLVM_LTO_STARTID: from which ID to start counting from for " + "a " + "bb\n" + " AFL_REAL_LD: use this lld linker instead of the compiled in " + "path\n" + "If anything fails - be sure to read README.lto.md!\n"); #endif + } SAYF( diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index c8056b9e..33b16817 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1043,11 +1043,11 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, } - if (fsrv->child_pid <= 0) { - + if (fsrv->child_pid <= 0) { + if (*stop_soon_p) { return 0; } FATAL("Fork server is misbehaving (OOM?)"); - + } exec_ms = read_s32_timed(fsrv->fsrv_st_fd, &fsrv->child_status, timeout, -- cgit v1.2.3 From 380051868a7531830d94d312f0f11b0e19e3284f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 10 Sep 2020 15:26:46 +0200 Subject: add libfuzzer custom mutator, minor enhancements and fixes --- src/afl-cc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 6bee8b38..a00b240d 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1508,9 +1508,9 @@ int main(int argc, char **argv, char **envp) { if (debug) { - SAYF(cMGN "[D]" cRST " cd \"%s\";", getthecwd()); + SAYF(cMGN "[D]" cRST " cd '%s';", getthecwd()); for (i = 0; i < argc; i++) - SAYF(" \"%s\"", argv[i]); + SAYF(" '%s'", argv[i]); SAYF("\n"); } @@ -1536,9 +1536,9 @@ int main(int argc, char **argv, char **envp) { if (debug) { - SAYF(cMGN "[D]" cRST " cd \"%s\";", getthecwd()); + SAYF(cMGN "[D]" cRST " cd '%s';", getthecwd()); for (i = 0; i < cc_par_cnt; i++) - SAYF(" \"%s\"", cc_params[i]); + SAYF(" '%s'", cc_params[i]); SAYF("\n"); } -- cgit v1.2.3 From a9ba907676a63777f82c4029f732670c9389e15e Mon Sep 17 00:00:00 2001 From: Choongwoo Han Date: Sun, 13 Sep 2020 21:25:02 +0900 Subject: Fix qemu argv construction (#555) --- src/afl-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index d66440aa..30c67909 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -146,7 +146,7 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { u8 * tmp, *cp = NULL, *rsl, *own_copy; memcpy(&new_argv[3], &argv[1], (int)(sizeof(char *)) * (argc - 1)); - new_argv[argc - 1] = NULL; + new_argv[argc + 2] = NULL; new_argv[2] = *target_path_p; new_argv[1] = "--"; -- cgit v1.2.3 From 060dbe12391b1e4957c09ef8b135f99f2a3bb121 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sun, 13 Sep 2020 14:26:24 +0200 Subject: wine argv fix --- src/afl-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 30c67909..ddae2ac1 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -228,7 +228,7 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { u8 * tmp, *cp = NULL, *rsl, *own_copy; memcpy(&new_argv[2], &argv[1], (int)(sizeof(char *)) * (argc - 1)); - new_argv[argc - 1] = NULL; + new_argv[argc + 2] = NULL; new_argv[1] = *target_path_p; -- cgit v1.2.3 From 7cdbe3173ef773562e5f117d03a823cd2786a457 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sun, 13 Sep 2020 15:00:10 +0200 Subject: fixed ngram size unset --- src/afl-cc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index a00b240d..c3b8959d 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1108,7 +1108,7 @@ int main(int argc, char **argv, char **envp) { if (!*ptr) { - if ((ptr = getenv("AFL_LLVM_NGRAM_SIZE")) != NULL) + if ((ptr = getenv("AFL_LLVM_NGRAM_SIZE")) == NULL) FATAL( "you must set the NGRAM size with (e.g. for value 2) " "AFL_LLVM_INSTRUMENT=ngram-2"); -- cgit v1.2.3 From 4561a9590fc9a8c9ef3676b119f04c2e6d0794c0 Mon Sep 17 00:00:00 2001 From: Edznux Date: Thu, 17 Sep 2020 01:29:09 +0200 Subject: WIP. basic state working: submitting statsd metrics (path, crashes, hangs) --- src/afl-fuzz-run.c | 5 ++- src/afl-fuzz-statsd.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 src/afl-fuzz-statsd.c (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index d71ec339..8dc0b334 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -901,7 +901,10 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { afl->stage_cur + 1 == afl->stage_max) { show_stats(afl); - + if(send_statsd_metric(afl)){ + //Change me to something realistic; don't fail on connection / lookup fail for metrics... + exit(1); + } } return 0; diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c new file mode 100644 index 00000000..aa12ca9a --- /dev/null +++ b/src/afl-fuzz-statsd.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "afl-fuzz.h" + + +int sock = 0; +struct sockaddr_in server; +int error = 0; + +int statsd_init(char *host, int port){ + if((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){ + perror("socket"); + exit(1); + } + + memset(&server, 0, sizeof(server)); + server.sin_family = AF_INET; + server.sin_port = htons(port); + + struct addrinfo *result; + struct addrinfo hints; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + + if ( (error = getaddrinfo(host, NULL, &hints, &result)) ) { + perror("getaddrinfo"); + exit(1); + } + + memcpy(&(server.sin_addr), &((struct sockaddr_in*)result->ai_addr)->sin_addr, sizeof(struct in_addr)); + freeaddrinfo(result); + + return 0; +} + +int send_statsd_metric(afl_state_t *afl){ + u64 cur_ms = get_cur_time(); + if (cur_ms - afl->stats_last_plot_ms < 1000) { + return 0; + } + + error = statsd_init("127.0.0.1", 12345); + if (error){ + perror("Failed to init statsd client. Aborting"); + return -1; + } + + if(!sock){ + perror("sock"); + return -1; + } + char buff[512]; + statsd_format_metric(afl, buff, 512); + + if (sendto(sock, buff, strlen(buff), 0, (struct sockaddr *) &server, sizeof(server)) == -1) { + perror("sendto"); + return -1; + } + close(sock); + sock=0; + + return 0; +} + + +void statsd_format_metric(afl_state_t *afl, char *buff, int bufflen){ + char *format = "fuzzing.afl.cycle_done:%llu|c\n" + "fuzzing.afl.total_path:%lu|c\n" + "fuzzing.afl.unique_crashes:%llu|c\n" + "fuzzing.afl.total_crashes:%llu|c\n" + "fuzzing.afl.unique_hangs:%llu|c\n"; + snprintf(buff, bufflen, format, + afl->queue_cycle, + afl->queued_paths, + afl->unique_crashes, + afl->total_crashes, + afl->unique_hangs + ); +} \ No newline at end of file -- cgit v1.2.3 From 9eed8fe58895fd4a20aa7b5f180b1bfaebf42cd7 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Fri, 18 Sep 2020 09:02:43 +0200 Subject: portability: type -> command -v, compiler warnings --- src/afl-fuzz-init.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 29c8c6fa..cbac3822 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -311,7 +311,7 @@ void bind_to_free_cpu(afl_state_t *afl) { } - for (i = 0; i < proccount; i++) { + for (i = 0; i < (s32)proccount; i++) { if (procs[i].p_cpuid < sizeof(cpu_used) && procs[i].p_pctcpu > 0) cpu_used[procs[i].p_cpuid] = 1; @@ -2182,6 +2182,8 @@ void check_cpu_governor(afl_state_t *afl) { "drop.\n", min / 1024, max / 1024); FATAL("Suboptimal CPU scaling governor"); +#else + (void)afl; #endif } -- cgit v1.2.3 From 44c0dc6d961853806a07fa05b948686392ea93fc Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 18 Sep 2020 12:19:27 +0200 Subject: fix expand havoc --- src/afl-fuzz.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 9196d78b..ea24011e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -242,11 +242,11 @@ static int stricmp(char const *a, char const *b) { int main(int argc, char **argv_orig, char **envp) { - s32 opt, i; - u64 prev_queued = 0; - u32 sync_interval_cnt = 0, seek_to, show_help = 0, map_size = MAP_SIZE; - u8 * extras_dir[4]; - u8 mem_limit_given = 0, exit_1 = 0, debug = 0, extras_dir_cnt = 0; + s32 opt, i; + u64 prev_queued = 0; + u32 sync_interval_cnt = 0, seek_to, show_help = 0, map_size = MAP_SIZE; + u8 *extras_dir[4]; + u8 mem_limit_given = 0, exit_1 = 0, debug = 0, extras_dir_cnt = 0, have_p = 0; char **use_argv; struct timeval tv; @@ -364,6 +364,8 @@ int main(int argc, char **argv_orig, char **envp) { } + have_p = 1; + break; case 'e': @@ -1364,7 +1366,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->expand_havoc = 2; break; case 2: - // afl->cycle_schedules = 1; + if (!have_p) afl->schedule = EXPLOIT; afl->expand_havoc = 3; break; case 3: -- cgit v1.2.3 From 7ff9800804f6f4f88b70d8aaf882b66e0ce40c8f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 19 Sep 2020 15:13:15 +0200 Subject: fix exploit, mmopt and rare schedule --- src/afl-fuzz-queue.c | 2 +- src/afl-fuzz.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 336b7f4f..ddd08f1c 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -710,7 +710,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { } - if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { + if (unlikely(afl->schedule >= EXPLOIT && afl->schedule <= QUAD)) { if (factor > MAX_FACTOR) { factor = MAX_FACTOR; } perf_score *= factor / POWER_BETA; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index ea24011e..11037f73 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1366,7 +1366,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->expand_havoc = 2; break; case 2: - if (!have_p) afl->schedule = EXPLOIT; + //if (!have_p) afl->schedule = EXPLOIT; afl->expand_havoc = 3; break; case 3: -- cgit v1.2.3 From a18523f0186548c27026f85151e354a085763ce1 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 19 Sep 2020 15:13:58 +0200 Subject: fix exploit, mmopt and rare schedule --- src/afl-fuzz.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 11037f73..8cfd79e2 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -246,7 +246,7 @@ int main(int argc, char **argv_orig, char **envp) { u64 prev_queued = 0; u32 sync_interval_cnt = 0, seek_to, show_help = 0, map_size = MAP_SIZE; u8 *extras_dir[4]; - u8 mem_limit_given = 0, exit_1 = 0, debug = 0, extras_dir_cnt = 0, have_p = 0; + u8 mem_limit_given = 0, exit_1 = 0, debug = 0, extras_dir_cnt = 0/*, have_p = 0*/; char **use_argv; struct timeval tv; @@ -364,7 +364,7 @@ int main(int argc, char **argv_orig, char **envp) { } - have_p = 1; + //have_p = 1; break; -- cgit v1.2.3 From 5f52f72761fd6bcb2cd9c97fb1cd3a6f05f28ccd Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 20 Sep 2020 14:58:08 +0200 Subject: set explore as default, fix schedule display --- src/afl-fuzz-state.c | 8 ++++---- src/afl-fuzz.c | 9 +++++---- 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 4e817843..ae45d571 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -30,9 +30,9 @@ s8 interesting_8[] = {INTERESTING_8}; s16 interesting_16[] = {INTERESTING_8, INTERESTING_16}; s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32}; -char *power_names[POWER_SCHEDULES_NUM] = {"explore", "exploit", "fast", - "coe", "lin", "quad", - "rare", "mmopt", "seek"}; +char *power_names[POWER_SCHEDULES_NUM] = {"explore", "mmopt", "exploit", + "fast", "coe", "lin", + "quad", "rare", "seek"}; /* Initialize MOpt "globals" for this afl state */ @@ -87,7 +87,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->w_end = 0.3; afl->g_max = 5000; afl->period_pilot_tmp = 5000.0; - afl->schedule = SEEK; /* Power schedule (default: SEEK) */ + afl->schedule = EXPLORE; /* Power schedule (default: EXPLORE) */ afl->havoc_max_mult = HAVOC_MAX_MULT; afl->clear_screen = 1; /* Window resized? */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 8cfd79e2..002be0be 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -90,7 +90,7 @@ static void usage(u8 *argv0, int more_help) { "Execution control settings:\n" " -p schedule - power schedules compute a seed's performance score:\n" - " -- see docs/power_schedules.md\n" " -f file - location read by the fuzzed program (default: stdin " @@ -246,7 +246,8 @@ int main(int argc, char **argv_orig, char **envp) { u64 prev_queued = 0; u32 sync_interval_cnt = 0, seek_to, show_help = 0, map_size = MAP_SIZE; u8 *extras_dir[4]; - u8 mem_limit_given = 0, exit_1 = 0, debug = 0, extras_dir_cnt = 0/*, have_p = 0*/; + u8 mem_limit_given = 0, exit_1 = 0, debug = 0, + extras_dir_cnt = 0 /*, have_p = 0*/; char **use_argv; struct timeval tv; @@ -364,7 +365,7 @@ int main(int argc, char **argv_orig, char **envp) { } - //have_p = 1; + // have_p = 1; break; @@ -1366,7 +1367,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->expand_havoc = 2; break; case 2: - //if (!have_p) afl->schedule = EXPLOIT; + // if (!have_p) afl->schedule = EXPLOIT; afl->expand_havoc = 3; break; case 3: -- cgit v1.2.3 From 52c135e1a2cf88f3b578af54962feb8272d12fd4 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 22 Sep 2020 02:05:31 +0200 Subject: fix warning --- src/afl-cc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index c3b8959d..c516dc4c 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1537,7 +1537,7 @@ int main(int argc, char **argv, char **envp) { if (debug) { SAYF(cMGN "[D]" cRST " cd '%s';", getthecwd()); - for (i = 0; i < cc_par_cnt; i++) + for (i = 0; i < (s32)cc_par_cnt; i++) SAYF(" '%s'", cc_params[i]); SAYF("\n"); -- cgit v1.2.3 From 888d63748a3c6aafd974cb9d96cdb8d3916e82bb Mon Sep 17 00:00:00 2001 From: Vitalii Akolzin Date: Thu, 24 Sep 2020 18:25:32 +0300 Subject: Fix potential endless loop in custom_mutator_stage Co-authored-by: Ivan Gulakov --- src/afl-fuzz-one.c | 64 ++++++++++++++++++++++++++++++++-------------------- src/afl-fuzz-queue.c | 2 ++ src/afl-fuzz-state.c | 2 ++ 3 files changed, 43 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 5737c1f5..edae2a88 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1696,50 +1696,58 @@ custom_mutator_stage: struct queue_entry *target; u32 tid; - u8 * new_buf; + u8 * new_buf = NULL; + u32 target_len = 0; - retry_external_pick: - /* Pick a random other queue entry for passing to external API */ + if (afl->ready_for_splicing_count > 1 || + (afl->ready_for_splicing_count == 1 && + afl->queue_cur->len == 1)) { - do { + retry_external_pick: + /* Pick a random other queue entry for passing to external API */ - tid = rand_below(afl, afl->queued_paths); + do { - } while (tid == afl->current_entry && afl->queued_paths > 1); + tid = rand_below(afl, afl->queued_paths); - afl->splicing_with = tid; - target = afl->queue_buf[tid]; + } while (tid == afl->current_entry && afl->queued_paths > 1); - /* Make sure that the target has a reasonable length. */ + afl->splicing_with = tid; + target = afl->queue_buf[tid]; - while (target && (target->len < 2 || target == afl->queue_cur) && - afl->queued_paths > 3) { + /* Make sure that the target has a reasonable length. */ - target = target->next; - ++afl->splicing_with; + while (target && (target->len < 2 || target == afl->queue_cur) && + afl->queued_paths > 2) { - } + target = target->next; + ++afl->splicing_with; - if (!target) { goto retry_external_pick; } + } - /* Read the additional testcase into a new buffer. */ - fd = open(target->fname, O_RDONLY); - if (unlikely(fd < 0)) { + if (!target) { goto retry_external_pick; } - PFATAL("Unable to open '%s'", target->fname); + /* Read the additional testcase into a new buffer. */ + fd = open(target->fname, O_RDONLY); + if (unlikely(fd < 0)) { - } + PFATAL("Unable to open '%s'", target->fname); - new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), target->len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - ck_read(fd, new_buf, target->len, target->fname); - close(fd); + } + + new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), target->len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } + ck_read(fd, new_buf, target->len, target->fname); + close(fd); + target_len = target->len; + + } u8 *mutated_buf = NULL; size_t mutated_size = el->afl_custom_fuzz(el->data, out_buf, len, &mutated_buf, new_buf, - target->len, max_seed_size); + target_len, max_seed_size); if (unlikely(!mutated_buf)) { @@ -2738,6 +2746,8 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { if (!afl->non_instrumented_mode && !afl->queue_cur->trim_done) { + u32 old_len = afl->queue_cur->len; + u8 res = trim_case(afl, afl->queue_cur, in_buf); if (res == FSRV_RUN_ERROR) { @@ -2759,6 +2769,10 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { len = afl->queue_cur->len; + /* maybe current entry stop being ready for splicing */ + if (old_len > 1 && afl->queue_cur->len == 1) + afl->ready_for_splicing_count--; + } memcpy(out_buf, in_buf, len); diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index ddd08f1c..14aa34fc 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -234,6 +234,8 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { } + if (q->len > 1) afl->ready_for_splicing_count++; + ++afl->queued_paths; ++afl->pending_not_fuzzed; diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index ae45d571..9f68bb51 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -155,6 +155,8 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->stats_last_execs = 0; afl->stats_avg_exec = -1; + afl->ready_for_splicing_count = 0; + init_mopt_globals(afl); list_append(&afl_states, afl); -- cgit v1.2.3 From a75e7594f78454a11e3d93b3cb4878a21e4e943f Mon Sep 17 00:00:00 2001 From: Vitalii Akolzin Date: Thu, 24 Sep 2020 18:50:59 +0300 Subject: Add comments Co-authored-by: Ivan Gulakov --- src/afl-fuzz-one.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index edae2a88..8c1aa179 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1699,6 +1699,9 @@ custom_mutator_stage: u8 * new_buf = NULL; u32 target_len = 0; + /* check if splicing is possible (if the only entry has len > 1 + * check it is not current entry) + */ if (afl->ready_for_splicing_count > 1 || (afl->ready_for_splicing_count == 1 && afl->queue_cur->len == 1)) { @@ -2769,7 +2772,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { len = afl->queue_cur->len; - /* maybe current entry stop being ready for splicing */ + /* maybe current entry is not ready for splicing anymore */ if (old_len > 1 && afl->queue_cur->len == 1) afl->ready_for_splicing_count--; -- cgit v1.2.3 From 6b3b1775b6b274bc62f9c79f686fc79fa110d0a8 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 25 Sep 2020 12:03:24 +0200 Subject: improving on splice candidate check patch --- src/afl-fuzz-one.c | 33 +++++++++------------------------ src/afl-fuzz-queue.c | 2 +- src/afl-fuzz-state.c | 48 +++++++++++++----------------------------------- 3 files changed, 23 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 8c1aa179..e96c4311 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1699,36 +1699,22 @@ custom_mutator_stage: u8 * new_buf = NULL; u32 target_len = 0; - /* check if splicing is possible (if the only entry has len > 1 - * check it is not current entry) - */ - if (afl->ready_for_splicing_count > 1 || - (afl->ready_for_splicing_count == 1 && - afl->queue_cur->len == 1)) { + /* check if splicing makes sense yet (enough entries) */ + if (likely(afl->ready_for_splicing_count > 1)) { - retry_external_pick: - /* Pick a random other queue entry for passing to external API */ + /* Pick a random other queue entry for passing to external API + that has the necessary length */ do { tid = rand_below(afl, afl->queued_paths); - } while (tid == afl->current_entry && afl->queued_paths > 1); - - afl->splicing_with = tid; - target = afl->queue_buf[tid]; - - /* Make sure that the target has a reasonable length. */ - - while (target && (target->len < 2 || target == afl->queue_cur) && - afl->queued_paths > 2) { - - target = target->next; - ++afl->splicing_with; + } while (unlikely(tid == afl->current_entry && - } + afl->queue_buf[tid]->len >= 4)); - if (!target) { goto retry_external_pick; } + target = afl->queue_buf[tid]; + afl->splicing_with = tid; /* Read the additional testcase into a new buffer. */ fd = open(target->fname, O_RDONLY); @@ -2773,8 +2759,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { len = afl->queue_cur->len; /* maybe current entry is not ready for splicing anymore */ - if (old_len > 1 && afl->queue_cur->len == 1) - afl->ready_for_splicing_count--; + if (unlikely(len <= 4 && old_len > 4)) afl->ready_for_splicing_count--; } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 14aa34fc..53c3e984 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -234,7 +234,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { } - if (q->len > 1) afl->ready_for_splicing_count++; + if (likely(q->len > 4)) afl->ready_for_splicing_count++; ++afl->queued_paths; ++afl->pending_not_fuzzed; diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 9f68bb51..5e0995fe 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -95,6 +95,11 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->stage_name = "init"; /* Name of the current fuzz stage */ afl->splicing_with = -1; /* Splicing with which test case? */ afl->cpu_to_bind = -1; + afl->cal_cycles = CAL_CYCLES; + afl->cal_cycles_long = CAL_CYCLES_LONG; + afl->hang_tmout = EXEC_TIMEOUT; + afl->stats_update_freq = 1; + afl->stats_avg_exec = -1; #ifdef HAVE_AFFINITY afl->cpu_aff = -1; /* Selected CPU core */ @@ -115,48 +120,13 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { // afl_state_t is not available in forkserver.c afl->fsrv.afl_ptr = (void *)afl; afl->fsrv.add_extra_func = (void (*)(void *, u8 *, u32)) & add_extra; - - afl->cal_cycles = CAL_CYCLES; - afl->cal_cycles_long = CAL_CYCLES_LONG; - afl->fsrv.exec_tmout = EXEC_TIMEOUT; - afl->hang_tmout = EXEC_TIMEOUT; - afl->fsrv.mem_limit = MEM_LIMIT; - - afl->stats_update_freq = 1; - afl->fsrv.dev_urandom_fd = -1; afl->fsrv.dev_null_fd = -1; - afl->fsrv.child_pid = -1; afl->fsrv.out_dir_fd = -1; - afl->cmplog_prev_timed_out = 0; - - /* statis file */ - afl->last_bitmap_cvg = 0; - afl->last_stability = 0; - afl->last_eps = 0; - - /* plot file saves from last run */ - afl->plot_prev_qp = 0; - afl->plot_prev_pf = 0; - afl->plot_prev_pnf = 0; - afl->plot_prev_ce = 0; - afl->plot_prev_md = 0; - afl->plot_prev_qc = 0; - afl->plot_prev_uc = 0; - afl->plot_prev_uh = 0; - - afl->stats_last_stats_ms = 0; - afl->stats_last_plot_ms = 0; - afl->stats_last_ms = 0; - afl->stats_last_execs = 0; - afl->stats_avg_exec = -1; - - afl->ready_for_splicing_count = 0; - init_mopt_globals(afl); list_append(&afl_states, afl); @@ -177,6 +147,14 @@ void read_afl_environment(afl_state_t *afl, char **envp) { WARNF("Potentially mistyped AFL environment variable: %s", env); issue_detected = 1; + } else if (strncmp(env, "USE_", 4) == 0) { + + WARNF( + "Potentially mistyped AFL environment variable: %s, did you mean " + "AFL_%s?", + env, env); + issue_detected = 1; + } else if (strncmp(env, "AFL_", 4) == 0) { int i = 0, match = 0; -- cgit v1.2.3 From a55e0d11891f0cc19a4ec6cc67c4e5e0d1c7f465 Mon Sep 17 00:00:00 2001 From: Edznux Date: Fri, 25 Sep 2020 23:28:15 +0200 Subject: WIP envs --- src/afl-fuzz-statsd.c | 70 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c index aa12ca9a..d09d1f6e 100644 --- a/src/afl-fuzz-statsd.c +++ b/src/afl-fuzz-statsd.c @@ -9,6 +9,9 @@ #include "afl-fuzz.h" +#define MAX_STATSD_PACKET_SIZE 1024 +#define MAX_TAG_LEN 200 + int sock = 0; struct sockaddr_in server; int error = 0; @@ -46,8 +49,21 @@ int send_statsd_metric(afl_state_t *afl){ if (cur_ms - afl->stats_last_plot_ms < 1000) { return 0; } + + u16 port = 8125; + char* host = "127.0.0.1"; - error = statsd_init("127.0.0.1", 12345); + char* port_env; + char* host_env; + if ((port_env = getenv("AFL_STATSD_PORT")) != NULL) { + port = atoi(port_env); + } + if ((host_env = getenv("AFL_STATSD_HOST")) != NULL) { + // sanitization check ? + host = host_env; + } + + error = statsd_init(host, port); if (error){ perror("Failed to init statsd client. Aborting"); return -1; @@ -57,31 +73,55 @@ int send_statsd_metric(afl_state_t *afl){ perror("sock"); return -1; } - char buff[512]; - statsd_format_metric(afl, buff, 512); - - if (sendto(sock, buff, strlen(buff), 0, (struct sockaddr *) &server, sizeof(server)) == -1) { - perror("sendto"); - return -1; + char *formatted[] = {}; + size_t *num_of_tags = 0; + statsd_format_metric(afl, &formatted, num_of_tags); + for (size_t i = 0; i < &num_of_tags; i++){ + printf("%ld\n", i); + printf("%s\n", formatted[i]); + if (sendto(sock, formatted[i], strlen(formatted[i]), 0, (struct sockaddr *) &server, sizeof(server)) == -1) { + perror("sendto"); + return -1; + } } + close(sock); sock=0; return 0; } +int statsd_format_metric(afl_state_t *afl, char *formatted[], size_t *num_of_tags){ + + char *tags = "key:value"; + + *num_of_tags = 0; // reset + + const char *metrics[] = { + "fuzzing.afl.cycle_done:%llu|g|#%s\n", + "fuzzing.afl.total_path:%lu|g|#%s\n", + "fuzzing.afl.unique_crashes:%llu|g|#%s\n", + "fuzzing.afl.total_crashes:%llu|g|#%s\n", + "fuzzing.afl.unique_hangs:%llu|g|#%s\n" + }; -void statsd_format_metric(afl_state_t *afl, char *buff, int bufflen){ - char *format = "fuzzing.afl.cycle_done:%llu|c\n" - "fuzzing.afl.total_path:%lu|c\n" - "fuzzing.afl.unique_crashes:%llu|c\n" - "fuzzing.afl.total_crashes:%llu|c\n" - "fuzzing.afl.unique_hangs:%llu|c\n"; - snprintf(buff, bufflen, format, + const int metricValues[] = { afl->queue_cycle, afl->queued_paths, afl->unique_crashes, afl->total_crashes, afl->unique_hangs - ); + }; + + *num_of_tags = sizeof(metrics)/sizeof(metrics[0]); + + for (size_t i = 0; i < &num_of_tags; i++){ + char *tmp = malloc(MAX_STATSD_PACKET_SIZE); + if(tmp == NULL){ + return -1; + } + snprintf(tmp, MAX_STATSD_PACKET_SIZE, metrics[i], metricValues[i], tags); + formatted[i] = tmp; + } + return 0; } \ No newline at end of file -- cgit v1.2.3 From e69b25e34be8028921389bbb114135c3028d0a3d Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 28 Sep 2020 10:13:00 +0200 Subject: increase havoc_stack_pow2 on no finds --- src/afl-fuzz-one.c | 4 ++-- src/afl-fuzz-state.c | 1 + src/afl-fuzz.c | 5 +++++ 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index e96c4311..c04b492b 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1884,7 +1884,7 @@ havoc_stage: for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { - u32 use_stacking = 1 << (1 + rand_below(afl, HAVOC_STACK_POW2)); + u32 use_stacking = 1 << (1 + rand_below(afl, afl->havoc_stack_pow2)); afl->stage_cur_val = use_stacking; @@ -3970,7 +3970,7 @@ pacemaker_fuzzing: for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { - u32 use_stacking = 1 << (1 + rand_below(afl, HAVOC_STACK_POW2)); + u32 use_stacking = 1 << (1 + rand_below(afl, afl->havoc_stack_pow2)); afl->stage_cur_val = use_stacking; diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 5e0995fe..a8e56e60 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -95,6 +95,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->stage_name = "init"; /* Name of the current fuzz stage */ afl->splicing_with = -1; /* Splicing with which test case? */ afl->cpu_to_bind = -1; + afl->havoc_stack_pow2 = HAVOC_STACK_POW2; afl->cal_cycles = CAL_CYCLES; afl->cal_cycles_long = CAL_CYCLES_LONG; afl->hang_tmout = EXEC_TIMEOUT; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 002be0be..28507857 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1368,9 +1368,14 @@ int main(int argc, char **argv_orig, char **envp) { break; case 2: // if (!have_p) afl->schedule = EXPLOIT; + afl->havoc_stack_pow2++; afl->expand_havoc = 3; break; case 3: + afl->havoc_stack_pow2++; + afl->expand_havoc = 4; + break; + case 4: // nothing else currently break; -- cgit v1.2.3 From e87eca7fe8ec3ed0ba79e7722350ad502b67218b Mon Sep 17 00:00:00 2001 From: Marcel Boehme Date: Tue, 29 Sep 2020 11:53:27 +0000 Subject: Patching and improving AFLFast schedules. --- src/afl-fuzz-bitmap.c | 18 +++-------- src/afl-fuzz-init.c | 8 +++++ src/afl-fuzz-queue.c | 84 +++++++++++++++++++++++++++++++++------------------ src/afl-fuzz.c | 7 +++++ 4 files changed, 74 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 1b9df624..64de86a2 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -555,19 +555,9 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); - struct queue_entry *q = afl->queue; - while (q) { - - if (q->exec_cksum == cksum) { - - ++q->n_fuzz; - break; - - } - - q = q->next; - - } + /* Saturated increment */ + if (afl->n_fuzz[cksum % n_fuzz_size] < 0xFFFFFFFF) + afl->n_fuzz[cksum % n_fuzz_size]++; } @@ -610,6 +600,8 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { afl->queue_top->exec_cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); + afl->n_fuzz[cksum % n_fuzz_size] = 1; + /* Try to calibrate inline; this also calls update_bitmap_score() when successful. */ diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index cbac3822..b825837f 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -729,6 +729,14 @@ void read_testcases(afl_state_t *afl, u8 *directory) { add_to_queue(afl, fn2, st.st_size >= MAX_FILE ? MAX_FILE : st.st_size, passed_det); + if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { + + u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); + + afl->n_fuzz[cksum % n_fuzz_size] = 1; + + } + } free(nl); /* not tracked */ diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 53c3e984..dfabba7b 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -25,6 +25,7 @@ #include "afl-fuzz.h" #include #include +#include /* Mark deterministic checks as done for a particular queue entry. We use the .state file to avoid repeating deterministic fuzzing when resuming aborted @@ -218,7 +219,6 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { q->len = len; q->depth = afl->cur_depth + 1; q->passed_det = passed_det; - q->n_fuzz = 1; q->trace_mini = NULL; if (q->depth > afl->max_depth) { afl->max_depth = q->depth; } @@ -307,8 +307,10 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u64 fav_factor; u64 fuzz_p2; - if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) - fuzz_p2 = next_pow2(q->n_fuzz); + if (unlikely(afl->schedule >= FAST && afl->schedule < RARE)) + fuzz_p2 = 0; // Skip the fuzz_p2 comparison + else if (unlikely(afl->schedule == RARE)) + fuzz_p2 = next_pow2(afl->n_fuzz[q->exec_cksum % n_fuzz_size]); else fuzz_p2 = q->fuzz_level; @@ -334,7 +336,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u64 top_rated_fav_factor; u64 top_rated_fuzz_p2; if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) - top_rated_fuzz_p2 = next_pow2(afl->top_rated[i]->n_fuzz); + top_rated_fuzz_p2 = next_pow2(afl->n_fuzz[afl->top_rated[i]->exec_cksum % n_fuzz_size]); else top_rated_fuzz_p2 = afl->top_rated[i]->fuzz_level; @@ -605,11 +607,10 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { } - u64 fuzz = q->n_fuzz; - u64 fuzz_total; + u32 n_paths; + double factor = 1.0; + long double fuzz_mu; - u32 n_paths, fuzz_mu; - u32 factor = 1; switch (afl->schedule) { @@ -624,60 +625,83 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { break; case COE: - fuzz_total = 0; + fuzz_mu = 0.0; n_paths = 0; + // Don't modify perf_score for unfuzzed seeds + if (q->fuzz_level == 0) break; + struct queue_entry *queue_it = afl->queue; while (queue_it) { - fuzz_total += queue_it->n_fuzz; + fuzz_mu += log2(afl->n_fuzz[q->exec_cksum % n_fuzz_size]); n_paths++; + queue_it = queue_it->next; } if (unlikely(!n_paths)) { FATAL("Queue state corrupt"); } - fuzz_mu = fuzz_total / n_paths; - if (fuzz <= fuzz_mu) { + fuzz_mu = fuzz_mu / n_paths; - if (q->fuzz_level < 16) { + if (log2(afl->n_fuzz[q->exec_cksum % n_fuzz_size]) > fuzz_mu) { - factor = ((u32)(1 << q->fuzz_level)); + /* Never skip favourites */ + if (!q->favored) factor = 0; - } else { + break; - factor = MAX_FACTOR; + } - } + // Fall through + case FAST: - } else { + // Don't modify unfuzzed seeds + if (q->fuzz_level == 0) break; - factor = 0; + switch ((u32)log2(afl->n_fuzz[q->exec_cksum % n_fuzz_size])) { - } + case 0 ... 1: + factor = 4; + break; - break; + case 2 ... 3: + factor = 3; + break; - case FAST: - if (q->fuzz_level < 16) { + case 4: + factor = 2; + break; - factor = ((u32)(1 << q->fuzz_level)) / (fuzz == 0 ? 1 : fuzz); + case 5: + break; - } else { + case 6: + if (!q->favored) factor = 0.8; + break; - factor = MAX_FACTOR / (fuzz == 0 ? 1 : next_pow2(fuzz)); + case 7: + if (!q->favored) factor = 0.6; + break; + + default: + if (!q->favored) factor = 0.4; + break; } + if (q->favored) + factor *= 1.15; + break; case LIN: - factor = q->fuzz_level / (fuzz == 0 ? 1 : fuzz); + factor = q->fuzz_level / (afl->n_fuzz[q->exec_cksum % n_fuzz_size] + 1); break; case QUAD: - factor = q->fuzz_level * q->fuzz_level / (fuzz == 0 ? 1 : fuzz); + factor = q->fuzz_level * q->fuzz_level / (afl->n_fuzz[q->exec_cksum % n_fuzz_size] + 1); break; case MMOPT: @@ -703,7 +727,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { // the more often fuzz result paths are equal to this queue entry, // reduce its value perf_score *= - (1 - (double)((double)q->n_fuzz / (double)afl->fsrv.total_execs)); + (1 - (double)((double)afl->n_fuzz[q->exec_cksum % n_fuzz_size] / (double)afl->fsrv.total_execs)); break; @@ -724,7 +748,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { perf_score *= 2; - } else if (perf_score < 1) { + } else if (afl->schedule != COE && perf_score < 1) { // Add a lower bound to AFLFast's energy assignment strategies perf_score = 1; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 28507857..889f753d 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -936,6 +936,13 @@ int main(int argc, char **argv_orig, char **envp) { } + /* Dynamically allocate memory for AFLFast schedules */ + if (afl->schedule >= FAST && afl->schedule <= RARE) { + + afl->n_fuzz = ck_alloc(n_fuzz_size * sizeof(u32)); + + } + if (get_afl_env("AFL_NO_FORKSRV")) { afl->no_forkserver = 1; } if (get_afl_env("AFL_NO_CPU_RED")) { afl->no_cpu_meter_red = 1; } if (get_afl_env("AFL_NO_ARITH")) { afl->no_arith = 1; } -- cgit v1.2.3 From 383cd487a2c28012c80341f8517e473120af4d19 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 29 Sep 2020 15:02:57 +0200 Subject: small improvements to Marcel's patch, fix laf-intel + redqueen crashes --- src/afl-fuzz-bitmap.c | 13 +++++++++---- src/afl-fuzz-init.c | 4 ++-- src/afl-fuzz-queue.c | 30 +++++++++++++++--------------- src/afl-fuzz.c | 2 +- 4 files changed, 27 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 64de86a2..a22223b9 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -556,8 +556,8 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); /* Saturated increment */ - if (afl->n_fuzz[cksum % n_fuzz_size] < 0xFFFFFFFF) - afl->n_fuzz[cksum % n_fuzz_size]++; + if (afl->n_fuzz[cksum % N_FUZZ_SIZE] < 0xFFFFFFFF) + afl->n_fuzz[cksum % N_FUZZ_SIZE]++; } @@ -597,10 +597,15 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (cksum) afl->queue_top->exec_cksum = cksum; else - afl->queue_top->exec_cksum = + cksum = afl->queue_top->exec_cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); - afl->n_fuzz[cksum % n_fuzz_size] = 1; + if (afl->schedule >= FAST && afl->schedule <= RARE) { + + afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE; + afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1; + + } /* Try to calibrate inline; this also calls update_bitmap_score() when successful. */ diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index b825837f..65478a78 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -732,8 +732,8 @@ void read_testcases(afl_state_t *afl, u8 *directory) { if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); - - afl->n_fuzz[cksum % n_fuzz_size] = 1; + afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE; + afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1; } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index dfabba7b..0d7d0314 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -308,9 +308,9 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u64 fuzz_p2; if (unlikely(afl->schedule >= FAST && afl->schedule < RARE)) - fuzz_p2 = 0; // Skip the fuzz_p2 comparison + fuzz_p2 = 0; // Skip the fuzz_p2 comparison else if (unlikely(afl->schedule == RARE)) - fuzz_p2 = next_pow2(afl->n_fuzz[q->exec_cksum % n_fuzz_size]); + fuzz_p2 = next_pow2(afl->n_fuzz[q->n_fuzz_entry]); else fuzz_p2 = q->fuzz_level; @@ -336,7 +336,8 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u64 top_rated_fav_factor; u64 top_rated_fuzz_p2; if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) - top_rated_fuzz_p2 = next_pow2(afl->n_fuzz[afl->top_rated[i]->exec_cksum % n_fuzz_size]); + top_rated_fuzz_p2 = + next_pow2(afl->n_fuzz[afl->top_rated[i]->n_fuzz_entry]); else top_rated_fuzz_p2 = afl->top_rated[i]->fuzz_level; @@ -607,11 +608,10 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { } - u32 n_paths; - double factor = 1.0; + u32 n_paths; + double factor = 1.0; long double fuzz_mu; - switch (afl->schedule) { case EXPLORE: @@ -634,7 +634,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { struct queue_entry *queue_it = afl->queue; while (queue_it) { - fuzz_mu += log2(afl->n_fuzz[q->exec_cksum % n_fuzz_size]); + fuzz_mu += log2(afl->n_fuzz[q->n_fuzz_entry]); n_paths++; queue_it = queue_it->next; @@ -645,7 +645,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { fuzz_mu = fuzz_mu / n_paths; - if (log2(afl->n_fuzz[q->exec_cksum % n_fuzz_size]) > fuzz_mu) { + if (log2(afl->n_fuzz[q->n_fuzz_entry]) > fuzz_mu) { /* Never skip favourites */ if (!q->favored) factor = 0; @@ -660,7 +660,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { // Don't modify unfuzzed seeds if (q->fuzz_level == 0) break; - switch ((u32)log2(afl->n_fuzz[q->exec_cksum % n_fuzz_size])) { + switch ((u32)log2(afl->n_fuzz[q->n_fuzz_entry])) { case 0 ... 1: factor = 4; @@ -691,17 +691,17 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { } - if (q->favored) - factor *= 1.15; + if (q->favored) factor *= 1.15; break; case LIN: - factor = q->fuzz_level / (afl->n_fuzz[q->exec_cksum % n_fuzz_size] + 1); + factor = q->fuzz_level / (afl->n_fuzz[q->n_fuzz_entry] + 1); break; case QUAD: - factor = q->fuzz_level * q->fuzz_level / (afl->n_fuzz[q->exec_cksum % n_fuzz_size] + 1); + factor = + q->fuzz_level * q->fuzz_level / (afl->n_fuzz[q->n_fuzz_entry] + 1); break; case MMOPT: @@ -726,8 +726,8 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { perf_score += (q->tc_ref * 10); // the more often fuzz result paths are equal to this queue entry, // reduce its value - perf_score *= - (1 - (double)((double)afl->n_fuzz[q->exec_cksum % n_fuzz_size] / (double)afl->fsrv.total_execs)); + perf_score *= (1 - (double)((double)afl->n_fuzz[q->n_fuzz_entry] / + (double)afl->fsrv.total_execs)); break; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 889f753d..273d1c14 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -939,7 +939,7 @@ int main(int argc, char **argv_orig, char **envp) { /* Dynamically allocate memory for AFLFast schedules */ if (afl->schedule >= FAST && afl->schedule <= RARE) { - afl->n_fuzz = ck_alloc(n_fuzz_size * sizeof(u32)); + afl->n_fuzz = ck_alloc(N_FUZZ_SIZE * sizeof(u32)); } -- cgit v1.2.3 From 223974336196a8f3617548e8ca88ee084794ed60 Mon Sep 17 00:00:00 2001 From: Edznux Date: Thu, 1 Oct 2020 00:11:01 +0200 Subject: Rewrote format metric to be simpler/more static --- src/afl-fuzz-statsd.c | 78 ++++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c index d09d1f6e..a53569c3 100644 --- a/src/afl-fuzz-statsd.c +++ b/src/afl-fuzz-statsd.c @@ -9,7 +9,7 @@ #include "afl-fuzz.h" -#define MAX_STATSD_PACKET_SIZE 1024 +#define MAX_STATSD_PACKET_SIZE 1400 #define MAX_TAG_LEN 200 int sock = 0; @@ -56,6 +56,7 @@ int send_statsd_metric(afl_state_t *afl){ char* port_env; char* host_env; if ((port_env = getenv("AFL_STATSD_PORT")) != NULL) { + // sanitization check ? port = atoi(port_env); } if ((host_env = getenv("AFL_STATSD_HOST")) != NULL) { @@ -73,55 +74,44 @@ int send_statsd_metric(afl_state_t *afl){ perror("sock"); return -1; } - char *formatted[] = {}; - size_t *num_of_tags = 0; - statsd_format_metric(afl, &formatted, num_of_tags); - for (size_t i = 0; i < &num_of_tags; i++){ - printf("%ld\n", i); - printf("%s\n", formatted[i]); - if (sendto(sock, formatted[i], strlen(formatted[i]), 0, (struct sockaddr *) &server, sizeof(server)) == -1) { - perror("sendto"); - return -1; - } + + char buff[MAX_STATSD_PACKET_SIZE] = {0}; + + statsd_format_metric(afl, buff, MAX_STATSD_PACKET_SIZE); + if (sendto(sock, buff, MAX_STATSD_PACKET_SIZE, 0, + (struct sockaddr *)&server, sizeof(server)) == -1) { + perror("sendto"); + return -1; } - + close(sock); sock=0; return 0; } -int statsd_format_metric(afl_state_t *afl, char *formatted[], size_t *num_of_tags){ +int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen){ + /* + metric format: + :|| + tags format: + #key:value,key:value,key + */ + char tags[MAX_TAG_LEN * 2] = {0}; + snprintf(tags, MAX_TAG_LEN * 2, + "banner:%s,afl_version:%s", + afl->use_banner, + VERSION); + // Sends multiple metrics with one UDP Packet. + // bufflen will limit to the max safe size. + snprintf(buff, bufflen, + "fuzzing.afl.cycle_done:%llu|g|#%s\n" + "fuzzing.afl.total_path:%u|g|#%s\n" + "fuzzing.afl.unique_crashes:%llu|g|#%s\n" + "fuzzing.afl.total_crashes:%llu|g|#%s\n" + "fuzzing.afl.unique_hangs:%llu|g|#%s\n", + afl->queue_cycle, tags, afl->queued_paths, tags, afl->unique_crashes, + tags, afl->total_crashes, tags, afl->unique_hangs, tags); - char *tags = "key:value"; - - *num_of_tags = 0; // reset - - const char *metrics[] = { - "fuzzing.afl.cycle_done:%llu|g|#%s\n", - "fuzzing.afl.total_path:%lu|g|#%s\n", - "fuzzing.afl.unique_crashes:%llu|g|#%s\n", - "fuzzing.afl.total_crashes:%llu|g|#%s\n", - "fuzzing.afl.unique_hangs:%llu|g|#%s\n" - }; - - const int metricValues[] = { - afl->queue_cycle, - afl->queued_paths, - afl->unique_crashes, - afl->total_crashes, - afl->unique_hangs - }; - - *num_of_tags = sizeof(metrics)/sizeof(metrics[0]); - - for (size_t i = 0; i < &num_of_tags; i++){ - char *tmp = malloc(MAX_STATSD_PACKET_SIZE); - if(tmp == NULL){ - return -1; - } - snprintf(tmp, MAX_STATSD_PACKET_SIZE, metrics[i], metricValues[i], tags); - formatted[i] = tmp; - } - return 0; + return 0; } \ No newline at end of file -- cgit v1.2.3 From 26dcddab0cdb3ca662746b1fd02cd58de3266269 Mon Sep 17 00:00:00 2001 From: Edznux Date: Sat, 3 Oct 2020 23:56:55 +0200 Subject: Add config ifdef --- src/afl-fuzz-run.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 8dc0b334..b7c4ae05 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -901,10 +901,12 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { afl->stage_cur + 1 == afl->stage_max) { show_stats(afl); + #ifdef USE_STATSD if(send_statsd_metric(afl)){ //Change me to something realistic; don't fail on connection / lookup fail for metrics... exit(1); } + #endif } return 0; -- cgit v1.2.3 From ff8c6d24156811333c855755fea8fafc43e133bc Mon Sep 17 00:00:00 2001 From: Edznux Date: Sun, 4 Oct 2020 03:22:28 +0200 Subject: Adds other metrics --- src/afl-fuzz-statsd.c | 74 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c index a53569c3..d9cd12d2 100644 --- a/src/afl-fuzz-statsd.c +++ b/src/afl-fuzz-statsd.c @@ -9,14 +9,15 @@ #include "afl-fuzz.h" -#define MAX_STATSD_PACKET_SIZE 1400 +#define MAX_STATSD_PACKET_SIZE 4096 #define MAX_TAG_LEN 200 +#define METRIC_PREFIX "fuzzing" int sock = 0; struct sockaddr_in server; int error = 0; -int statsd_init(char *host, int port){ +int statsd_socket_init(char *host, int port){ if((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){ perror("socket"); exit(1); @@ -45,11 +46,9 @@ int statsd_init(char *host, int port){ } int send_statsd_metric(afl_state_t *afl){ - u64 cur_ms = get_cur_time(); - if (cur_ms - afl->stats_last_plot_ms < 1000) { - return 0; - } - + /* default port and host. + Will be overwritten by AFL_STATSD_PORT and AFL_STATSD_HOST environment variable, if they exists. + */ u16 port = 8125; char* host = "127.0.0.1"; @@ -64,7 +63,7 @@ int send_statsd_metric(afl_state_t *afl){ host = host_env; } - error = statsd_init(host, port); + error = statsd_socket_init(host, port); if (error){ perror("Failed to init statsd client. Aborting"); return -1; @@ -78,7 +77,7 @@ int send_statsd_metric(afl_state_t *afl){ char buff[MAX_STATSD_PACKET_SIZE] = {0}; statsd_format_metric(afl, buff, MAX_STATSD_PACKET_SIZE); - if (sendto(sock, buff, MAX_STATSD_PACKET_SIZE, 0, + if (sendto(sock, buff, strlen(buff), 0, (struct sockaddr *)&server, sizeof(server)) == -1) { perror("sendto"); return -1; @@ -95,23 +94,62 @@ int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen){ metric format: :|| tags format: - #key:value,key:value,key + */ + #ifdef USE_STATSD_TAGS + /* #key:value,key:value,key */ char tags[MAX_TAG_LEN * 2] = {0}; snprintf(tags, MAX_TAG_LEN * 2, - "banner:%s,afl_version:%s", + "|#banner:%s,afl_version:%s", afl->use_banner, VERSION); + #else + char *tags = ""; + #endif // Sends multiple metrics with one UDP Packet. // bufflen will limit to the max safe size. snprintf(buff, bufflen, - "fuzzing.afl.cycle_done:%llu|g|#%s\n" - "fuzzing.afl.total_path:%u|g|#%s\n" - "fuzzing.afl.unique_crashes:%llu|g|#%s\n" - "fuzzing.afl.total_crashes:%llu|g|#%s\n" - "fuzzing.afl.unique_hangs:%llu|g|#%s\n", - afl->queue_cycle, tags, afl->queued_paths, tags, afl->unique_crashes, - tags, afl->total_crashes, tags, afl->unique_hangs, tags); + METRIC_PREFIX".cycle_done:%llu|g%s\n" + METRIC_PREFIX".cycles_wo_finds:%llu|g%s\n" + METRIC_PREFIX".execs_done:%llu|g%s\n" + METRIC_PREFIX".execs_per_sec:%0.02f|g%s\n" + METRIC_PREFIX".paths_total:%u|g%s\n" + METRIC_PREFIX".paths_favored:%u|g%s\n" + METRIC_PREFIX".paths_found:%u|g%s\n" + METRIC_PREFIX".paths_imported:%u|g%s\n" + METRIC_PREFIX".max_depth:%u|g%s\n" + METRIC_PREFIX".cur_path:%u|g%s\n" + METRIC_PREFIX".pending_favs:%u|g%s\n" + METRIC_PREFIX".pending_total:%u|g%s\n" + METRIC_PREFIX".variable_paths:%u|g%s\n" + METRIC_PREFIX".unique_crashes:%llu|g%s\n" + METRIC_PREFIX".unique_hangs:%llu|g%s\n" + METRIC_PREFIX".total_crashes:%llu|g%s\n" + METRIC_PREFIX".slowest_exec_ms:%u|g%s\n" + METRIC_PREFIX".edges_found:%u|g%s\n" + METRIC_PREFIX".var_byte_count:%u|g%s\n" + METRIC_PREFIX".havoc_expansion:%u|g%s\n", + afl->queue_cycle ? (afl->queue_cycle - 1) : 0, tags, + afl->cycles_wo_finds, tags, + afl->fsrv.total_execs, tags, + afl->fsrv.total_execs / ((double)(get_cur_time() - afl->start_time) / 1000), tags, + afl->queued_paths, tags, + afl->queued_favored, tags, + afl->queued_discovered, tags, + afl->queued_imported, tags, + afl->max_depth, tags, + afl->current_entry, tags, + afl->pending_favored, tags, + afl->pending_not_fuzzed, tags, + afl->queued_variable, tags, + afl->unique_crashes, tags, + afl->unique_hangs, tags, + afl->total_crashes, tags, + afl->slowest_exec_ms, tags, + count_non_255_bytes(afl, afl->virgin_bits), tags, + afl->var_byte_count, tags, + afl->expand_havoc, tags + ); return 0; } \ No newline at end of file -- cgit v1.2.3 From 6006cce0cf012884d1509c00ef0f088aeac66bb7 Mon Sep 17 00:00:00 2001 From: Edznux Date: Sun, 4 Oct 2020 03:24:09 +0200 Subject: Define config, change parent func to show_stats --- src/afl-fuzz-run.c | 6 ------ src/afl-fuzz-stats.c | 8 ++++++++ 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index b7c4ae05..6fa142d2 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -901,12 +901,6 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { afl->stage_cur + 1 == afl->stage_max) { show_stats(afl); - #ifdef USE_STATSD - if(send_statsd_metric(afl)){ - //Change me to something realistic; don't fail on connection / lookup fail for metrics... - exit(1); - } - #endif } return 0; diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 51eed14b..bbbe6ba6 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -422,6 +422,14 @@ void show_stats(afl_state_t *afl) { } + #ifdef USE_STATSD + if (cur_ms - afl->stats_last_stats_ms > STATSD_UPDATE_SEC * 1000) { + if(send_statsd_metric(afl)){ + WARNF("coundln't send statsd metric."); + } + } + #endif + /* Every now and then, write plot data. */ if (cur_ms - afl->stats_last_plot_ms > PLOT_UPDATE_SEC * 1000) { -- cgit v1.2.3 From ca6106a1dc5b39df9f167b3d30ea4472636564c9 Mon Sep 17 00:00:00 2001 From: Edznux Date: Sun, 4 Oct 2020 14:24:25 +0200 Subject: Refactor --- src/afl-fuzz-stats.c | 6 +++-- src/afl-fuzz-statsd.c | 73 ++++++++++++++++++++++++++------------------------- 2 files changed, 41 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index bbbe6ba6..ffef7647 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -423,8 +423,10 @@ void show_stats(afl_state_t *afl) { } #ifdef USE_STATSD - if (cur_ms - afl->stats_last_stats_ms > STATSD_UPDATE_SEC * 1000) { - if(send_statsd_metric(afl)){ + if (cur_ms - afl->statsd_last_send_ms > STATSD_UPDATE_SEC * 1000) { + /* reset counter, even if send failed. */ + afl->statsd_last_send_ms = cur_ms; + if(statsd_send_metric(afl)){ WARNF("coundln't send statsd metric."); } } diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c index d9cd12d2..5bd1b537 100644 --- a/src/afl-fuzz-statsd.c +++ b/src/afl-fuzz-statsd.c @@ -13,11 +13,12 @@ #define MAX_TAG_LEN 200 #define METRIC_PREFIX "fuzzing" -int sock = 0; struct sockaddr_in server; int error = 0; +int statds_sock = 0; int statsd_socket_init(char *host, int port){ + int sock; if((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){ perror("socket"); exit(1); @@ -42,72 +43,72 @@ int statsd_socket_init(char *host, int port){ memcpy(&(server.sin_addr), &((struct sockaddr_in*)result->ai_addr)->sin_addr, sizeof(struct in_addr)); freeaddrinfo(result); - return 0; + return sock; } -int send_statsd_metric(afl_state_t *afl){ - /* default port and host. +int statsd_send_metric(afl_state_t *afl){ + + char buff[MAX_STATSD_PACKET_SIZE] = {0}; + /* Default port and host. Will be overwritten by AFL_STATSD_PORT and AFL_STATSD_HOST environment variable, if they exists. - */ - u16 port = 8125; - char* host = "127.0.0.1"; + */ + u16 port = STATSD_DEFAULT_PORT; + char* host = STATSD_DEFAULT_HOST; char* port_env; char* host_env; if ((port_env = getenv("AFL_STATSD_PORT")) != NULL) { - // sanitization check ? port = atoi(port_env); } if ((host_env = getenv("AFL_STATSD_HOST")) != NULL) { - // sanitization check ? host = host_env; } - - error = statsd_socket_init(host, port); - if (error){ - perror("Failed to init statsd client. Aborting"); - return -1; - } - - if(!sock){ - perror("sock"); - return -1; - } - char buff[MAX_STATSD_PACKET_SIZE] = {0}; + /* statds_sock is a global variable. We set it once in the beginning and reuse the socket. + If the sendto later fail, we reset it to 0 to be able to recreate it. + */ + if(!statds_sock){ + statds_sock = statsd_socket_init(host, port); + if(!statds_sock){ + perror("Cannot create socket"); + return -1; + } + } statsd_format_metric(afl, buff, MAX_STATSD_PACKET_SIZE); - if (sendto(sock, buff, strlen(buff), 0, - (struct sockaddr *)&server, sizeof(server)) == -1) { - perror("sendto"); - return -1; + if (sendto(statds_sock, buff, strlen(buff), 0, (struct sockaddr *)&server, sizeof(server)) == -1) { + if(!close(statds_sock)){ + perror("Cannot close socket"); + } + statds_sock = 0; + perror("Cannot sendto"); + return -1; } - close(sock); - sock=0; - return 0; } int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen){ - /* - metric format: - :|| - tags format: + /* Metric format: + :| */ #ifdef USE_STATSD_TAGS - /* #key:value,key:value,key + /* Tags format: DogStatsD + :||#key:value,key:value,key */ char tags[MAX_TAG_LEN * 2] = {0}; snprintf(tags, MAX_TAG_LEN * 2, "|#banner:%s,afl_version:%s", afl->use_banner, VERSION); - #else + #else + /* No tags. + */ char *tags = ""; #endif - // Sends multiple metrics with one UDP Packet. - // bufflen will limit to the max safe size. + /* Sends multiple metrics with one UDP Packet. + bufflen will limit to the max safe size. + */ snprintf(buff, bufflen, METRIC_PREFIX".cycle_done:%llu|g%s\n" METRIC_PREFIX".cycles_wo_finds:%llu|g%s\n" -- cgit v1.2.3 From b0de6fed11d4a8de8f016f1d8db0cb19a6b96eb2 Mon Sep 17 00:00:00 2001 From: Edznux Date: Sun, 4 Oct 2020 14:29:50 +0200 Subject: Mention tags format in macro's name --- src/afl-fuzz-statsd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c index 5bd1b537..298138be 100644 --- a/src/afl-fuzz-statsd.c +++ b/src/afl-fuzz-statsd.c @@ -92,7 +92,7 @@ int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen){ /* Metric format: :| */ - #ifdef USE_STATSD_TAGS + #ifdef USE_DOGSTATSD_TAGS /* Tags format: DogStatsD :||#key:value,key:value,key */ -- cgit v1.2.3 From 1a12db1b59e792c7a46e606fba60bdf855d00c29 Mon Sep 17 00:00:00 2001 From: Edznux Date: Sun, 4 Oct 2020 16:11:05 +0200 Subject: Code format --- src/afl-fuzz-run.c | 1 + src/afl-fuzz-stats.c | 11 ++- src/afl-fuzz-statsd.c | 256 +++++++++++++++++++++++++------------------------- 3 files changed, 135 insertions(+), 133 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 5e74dff3..ee22b0f6 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -903,6 +903,7 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { afl->stage_cur + 1 == afl->stage_max) { show_stats(afl); + } return 0; diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 2f1e3367..942670b4 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -423,15 +423,16 @@ void show_stats(afl_state_t *afl) { } - #ifdef USE_STATSD +#ifdef USE_STATSD if (cur_ms - afl->statsd_last_send_ms > STATSD_UPDATE_SEC * 1000) { + /* reset counter, even if send failed. */ afl->statsd_last_send_ms = cur_ms; - if(statsd_send_metric(afl)){ - WARNF("coundln't send statsd metric."); - } + if (statsd_send_metric(afl)) { WARNF("coundln't send statsd metric."); } + } - #endif + +#endif /* Every now and then, write plot data. */ diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c index 298138be..e94f090c 100644 --- a/src/afl-fuzz-statsd.c +++ b/src/afl-fuzz-statsd.c @@ -8,149 +8,149 @@ #include #include "afl-fuzz.h" - #define MAX_STATSD_PACKET_SIZE 4096 #define MAX_TAG_LEN 200 #define METRIC_PREFIX "fuzzing" struct sockaddr_in server; -int error = 0; -int statds_sock = 0; - -int statsd_socket_init(char *host, int port){ - int sock; - if((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){ - perror("socket"); - exit(1); - } +int error = 0; +int statds_sock = 0; - memset(&server, 0, sizeof(server)); - server.sin_family = AF_INET; - server.sin_port = htons(port); - - struct addrinfo *result; - struct addrinfo hints; +int statsd_socket_init(char *host, int port) { - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_DGRAM; + int sock; + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { - if ( (error = getaddrinfo(host, NULL, &hints, &result)) ) { - perror("getaddrinfo"); - exit(1); - } + FATAL("Failed to create socket"); + + } + + memset(&server, 0, sizeof(server)); + server.sin_family = AF_INET; + server.sin_port = htons(port); + + struct addrinfo *result; + struct addrinfo hints; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; - memcpy(&(server.sin_addr), &((struct sockaddr_in*)result->ai_addr)->sin_addr, sizeof(struct in_addr)); - freeaddrinfo(result); + if ((error = getaddrinfo(host, NULL, &hints, &result))) { + + FATAL("Fail to getaddrinfo"); + + } + + memcpy(&(server.sin_addr), &((struct sockaddr_in *)result->ai_addr)->sin_addr, + sizeof(struct in_addr)); + freeaddrinfo(result); + + return sock; - return sock; } -int statsd_send_metric(afl_state_t *afl){ - - char buff[MAX_STATSD_PACKET_SIZE] = {0}; - /* Default port and host. - Will be overwritten by AFL_STATSD_PORT and AFL_STATSD_HOST environment variable, if they exists. - */ - u16 port = STATSD_DEFAULT_PORT; - char* host = STATSD_DEFAULT_HOST; - - char* port_env; - char* host_env; - if ((port_env = getenv("AFL_STATSD_PORT")) != NULL) { - port = atoi(port_env); - } - if ((host_env = getenv("AFL_STATSD_HOST")) != NULL) { - host = host_env; - } +int statsd_send_metric(afl_state_t *afl) { - /* statds_sock is a global variable. We set it once in the beginning and reuse the socket. - If the sendto later fail, we reset it to 0 to be able to recreate it. - */ - if(!statds_sock){ - statds_sock = statsd_socket_init(host, port); - if(!statds_sock){ - perror("Cannot create socket"); - return -1; - } - } + char buff[MAX_STATSD_PACKET_SIZE] = {0}; + /* Default port and host. + Will be overwritten by AFL_STATSD_PORT and AFL_STATSD_HOST environment + variable, if they exists. + */ + u16 port = STATSD_DEFAULT_PORT; + char *host = STATSD_DEFAULT_HOST; + + char *port_env; + char *host_env; + if ((port_env = getenv("AFL_STATSD_PORT")) != NULL) { port = atoi(port_env); } + if ((host_env = getenv("AFL_STATSD_HOST")) != NULL) { host = host_env; } + + /* statds_sock is a global variable. We set it once in the beginning and reuse + the socket. If the sendto later fail, we reset it to 0 to be able to recreate + it. + */ + if (!statds_sock) { + + statds_sock = statsd_socket_init(host, port); + if (!statds_sock) { + + WARNF("Cannot create socket"); + return -1; - statsd_format_metric(afl, buff, MAX_STATSD_PACKET_SIZE); - if (sendto(statds_sock, buff, strlen(buff), 0, (struct sockaddr *)&server, sizeof(server)) == -1) { - if(!close(statds_sock)){ - perror("Cannot close socket"); - } - statds_sock = 0; - perror("Cannot sendto"); - return -1; } - return 0; + } + + statsd_format_metric(afl, buff, MAX_STATSD_PACKET_SIZE); + if (sendto(statds_sock, buff, strlen(buff), 0, (struct sockaddr *)&server, + sizeof(server)) == -1) { + + if (!close(statds_sock)) { perror("Cannot close socket"); } + statds_sock = 0; + WARNF("Cannot sendto"); + return -1; + + } + + return 0; + +} + +int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen) { + +/* Metric format: +:| +*/ +#ifdef USE_DOGSTATSD_TAGS + /* Tags format: DogStatsD + :||#key:value,key:value,key + */ + char tags[MAX_TAG_LEN * 2] = {0}; + snprintf(tags, MAX_TAG_LEN * 2, "|#banner:%s,afl_version:%s", afl->use_banner, + VERSION); +#else + /* No tags. + */ + char *tags = ""; +#endif + /* Sends multiple metrics with one UDP Packet. + bufflen will limit to the max safe size. + */ + snprintf(buff, bufflen, + METRIC_PREFIX ".cycle_done:%llu|g%s\n" METRIC_PREFIX + ".cycles_wo_finds:%llu|g%s\n" METRIC_PREFIX + ".execs_done:%llu|g%s\n" METRIC_PREFIX + ".execs_per_sec:%0.02f|g%s\n" METRIC_PREFIX + ".paths_total:%u|g%s\n" METRIC_PREFIX + ".paths_favored:%u|g%s\n" METRIC_PREFIX + ".paths_found:%u|g%s\n" METRIC_PREFIX + ".paths_imported:%u|g%s\n" METRIC_PREFIX + ".max_depth:%u|g%s\n" METRIC_PREFIX + ".cur_path:%u|g%s\n" METRIC_PREFIX + ".pending_favs:%u|g%s\n" METRIC_PREFIX + ".pending_total:%u|g%s\n" METRIC_PREFIX + ".variable_paths:%u|g%s\n" METRIC_PREFIX + ".unique_crashes:%llu|g%s\n" METRIC_PREFIX + ".unique_hangs:%llu|g%s\n" METRIC_PREFIX + ".total_crashes:%llu|g%s\n" METRIC_PREFIX + ".slowest_exec_ms:%u|g%s\n" METRIC_PREFIX + ".edges_found:%u|g%s\n" METRIC_PREFIX + ".var_byte_count:%u|g%s\n" METRIC_PREFIX + ".havoc_expansion:%u|g%s\n", + afl->queue_cycle ? (afl->queue_cycle - 1) : 0, tags, + afl->cycles_wo_finds, tags, afl->fsrv.total_execs, tags, + afl->fsrv.total_execs / + ((double)(get_cur_time() - afl->start_time) / 1000), + tags, afl->queued_paths, tags, afl->queued_favored, tags, + afl->queued_discovered, tags, afl->queued_imported, tags, + afl->max_depth, tags, afl->current_entry, tags, afl->pending_favored, + tags, afl->pending_not_fuzzed, tags, afl->queued_variable, tags, + afl->unique_crashes, tags, afl->unique_hangs, tags, + afl->total_crashes, tags, afl->slowest_exec_ms, tags, + count_non_255_bytes(afl, afl->virgin_bits), tags, + afl->var_byte_count, tags, afl->expand_havoc, tags); + + return 0; + } -int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen){ - /* Metric format: - :| - */ - #ifdef USE_DOGSTATSD_TAGS - /* Tags format: DogStatsD - :||#key:value,key:value,key - */ - char tags[MAX_TAG_LEN * 2] = {0}; - snprintf(tags, MAX_TAG_LEN * 2, - "|#banner:%s,afl_version:%s", - afl->use_banner, - VERSION); - #else - /* No tags. - */ - char *tags = ""; - #endif - /* Sends multiple metrics with one UDP Packet. - bufflen will limit to the max safe size. - */ - snprintf(buff, bufflen, - METRIC_PREFIX".cycle_done:%llu|g%s\n" - METRIC_PREFIX".cycles_wo_finds:%llu|g%s\n" - METRIC_PREFIX".execs_done:%llu|g%s\n" - METRIC_PREFIX".execs_per_sec:%0.02f|g%s\n" - METRIC_PREFIX".paths_total:%u|g%s\n" - METRIC_PREFIX".paths_favored:%u|g%s\n" - METRIC_PREFIX".paths_found:%u|g%s\n" - METRIC_PREFIX".paths_imported:%u|g%s\n" - METRIC_PREFIX".max_depth:%u|g%s\n" - METRIC_PREFIX".cur_path:%u|g%s\n" - METRIC_PREFIX".pending_favs:%u|g%s\n" - METRIC_PREFIX".pending_total:%u|g%s\n" - METRIC_PREFIX".variable_paths:%u|g%s\n" - METRIC_PREFIX".unique_crashes:%llu|g%s\n" - METRIC_PREFIX".unique_hangs:%llu|g%s\n" - METRIC_PREFIX".total_crashes:%llu|g%s\n" - METRIC_PREFIX".slowest_exec_ms:%u|g%s\n" - METRIC_PREFIX".edges_found:%u|g%s\n" - METRIC_PREFIX".var_byte_count:%u|g%s\n" - METRIC_PREFIX".havoc_expansion:%u|g%s\n", - afl->queue_cycle ? (afl->queue_cycle - 1) : 0, tags, - afl->cycles_wo_finds, tags, - afl->fsrv.total_execs, tags, - afl->fsrv.total_execs / ((double)(get_cur_time() - afl->start_time) / 1000), tags, - afl->queued_paths, tags, - afl->queued_favored, tags, - afl->queued_discovered, tags, - afl->queued_imported, tags, - afl->max_depth, tags, - afl->current_entry, tags, - afl->pending_favored, tags, - afl->pending_not_fuzzed, tags, - afl->queued_variable, tags, - afl->unique_crashes, tags, - afl->unique_hangs, tags, - afl->total_crashes, tags, - afl->slowest_exec_ms, tags, - count_non_255_bytes(afl, afl->virgin_bits), tags, - afl->var_byte_count, tags, - afl->expand_havoc, tags - ); - - return 0; -} \ No newline at end of file -- cgit v1.2.3 From bab60b68d968492d689bc5963bd775b10c6292e8 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 4 Oct 2020 20:45:59 +0200 Subject: changed the default schedule to coe --- src/afl-fuzz-state.c | 2 +- src/afl-fuzz.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index a8e56e60..4a1e739f 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -87,7 +87,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->w_end = 0.3; afl->g_max = 5000; afl->period_pilot_tmp = 5000.0; - afl->schedule = EXPLORE; /* Power schedule (default: EXPLORE) */ + afl->schedule = COE; /* Power schedule (default: COE) */ afl->havoc_max_mult = HAVOC_MAX_MULT; afl->clear_screen = 1; /* Window resized? */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 273d1c14..2f8aa3fd 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -90,7 +90,7 @@ static void usage(u8 *argv0, int more_help) { "Execution control settings:\n" " -p schedule - power schedules compute a seed's performance score:\n" - " -- see docs/power_schedules.md\n" " -f file - location read by the fuzzed program (default: stdin " @@ -928,7 +928,7 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Using seek power schedule (SEEK)"); break; case EXPLORE: - OKF("Using exploration-based constant power schedule (EXPLORE, default)"); + OKF("Using exploration-based constant power schedule (EXPLORE)"); break; default: FATAL("Unknown power schedule"); -- cgit v1.2.3 From 9b112fde1a7d776b07f0cb656d11c6151902d2c3 Mon Sep 17 00:00:00 2001 From: Edznux Date: Mon, 5 Oct 2020 19:29:37 +0200 Subject: Add help for AFL_STATSD_HOST & AFL_STATSD_PORT env var --- src/afl-fuzz.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index ea24011e..0b08f426 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -194,6 +194,8 @@ static void usage(u8 *argv0, int more_help) { "AFL_SKIP_BIN_CHECK: skip the check, if the target is an executable\n" "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n" "AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n" + "AFL_STATSD_HOST: change default statsd host. (default 127.0.0.1)" + "AFL_STATSD_PORT: change default statsd port (default: 8125)" "AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n" //"AFL_PERSISTENT: not supported anymore -> no effect, just a warning\n" //"AFL_DEFER_FORKSRV: not supported anymore -> no effect, just a warning\n" -- cgit v1.2.3 From 2bf3a70e2b5cd0961cb5b1d525f3fd58c4408ba5 Mon Sep 17 00:00:00 2001 From: Edznux Date: Mon, 5 Oct 2020 22:01:50 +0200 Subject: Correctly handle env var. --- src/afl-fuzz-state.c | 13 +++++++++++++ src/afl-fuzz-statsd.c | 6 ++---- 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 4e817843..aefa226d 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -363,6 +363,19 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_forksrv_init_tmout = (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_STATSD_HOST", + + afl_environment_variable_len)) { + + afl->afl_env.afl_statsd_host = + (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_STATSD_PORT", + + afl_environment_variable_len)) { + + afl->afl_env.afl_statsd_port = + (u8 *)get_afl_env(afl_environment_variables[i]); + } } else { diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c index e94f090c..7ae2efca 100644 --- a/src/afl-fuzz-statsd.c +++ b/src/afl-fuzz-statsd.c @@ -60,10 +60,8 @@ int statsd_send_metric(afl_state_t *afl) { u16 port = STATSD_DEFAULT_PORT; char *host = STATSD_DEFAULT_HOST; - char *port_env; - char *host_env; - if ((port_env = getenv("AFL_STATSD_PORT")) != NULL) { port = atoi(port_env); } - if ((host_env = getenv("AFL_STATSD_HOST")) != NULL) { host = host_env; } + if (afl->afl_env.afl_statsd_port) { port = atoi(afl->afl_env.afl_statsd_port); } + if (afl->afl_env.afl_statsd_host) { host = afl->afl_env.afl_statsd_host; } /* statds_sock is a global variable. We set it once in the beginning and reuse the socket. If the sendto later fail, we reset it to 0 to be able to recreate -- cgit v1.2.3 From 916b6fd3171bab1b17e576e088f094080ff5f6cf Mon Sep 17 00:00:00 2001 From: Edznux Date: Mon, 5 Oct 2020 22:21:01 +0200 Subject: Refactor global var into afl_state_t struct --- src/afl-fuzz-statsd.c | 51 +++++++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c index 7ae2efca..0ec1bcb7 100644 --- a/src/afl-fuzz-statsd.c +++ b/src/afl-fuzz-statsd.c @@ -12,11 +12,16 @@ #define MAX_TAG_LEN 200 #define METRIC_PREFIX "fuzzing" -struct sockaddr_in server; -int error = 0; -int statds_sock = 0; +int statsd_socket_init(afl_state_t *afl) { + /* Default port and host. + Will be overwritten by AFL_STATSD_PORT and AFL_STATSD_HOST environment + variable, if they exists. + */ + u16 port = STATSD_DEFAULT_PORT; + char *host = STATSD_DEFAULT_HOST; -int statsd_socket_init(char *host, int port) { + if (afl->afl_env.afl_statsd_port) { port = atoi(afl->afl_env.afl_statsd_port); } + if (afl->afl_env.afl_statsd_host) { host = afl->afl_env.afl_statsd_host; } int sock; if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { @@ -25,9 +30,9 @@ int statsd_socket_init(char *host, int port) { } - memset(&server, 0, sizeof(server)); - server.sin_family = AF_INET; - server.sin_port = htons(port); + memset(&afl->statsd_server, 0, sizeof(afl->statsd_server)); + afl->statsd_server.sin_family = AF_INET; + afl->statsd_server.sin_port = htons(port); struct addrinfo *result; struct addrinfo hints; @@ -36,13 +41,13 @@ int statsd_socket_init(char *host, int port) { hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; - if ((error = getaddrinfo(host, NULL, &hints, &result))) { + if ((getaddrinfo(host, NULL, &hints, &result))) { FATAL("Fail to getaddrinfo"); } - memcpy(&(server.sin_addr), &((struct sockaddr_in *)result->ai_addr)->sin_addr, + memcpy(&(afl->statsd_server.sin_addr), &((struct sockaddr_in *)result->ai_addr)->sin_addr, sizeof(struct in_addr)); freeaddrinfo(result); @@ -53,24 +58,14 @@ int statsd_socket_init(char *host, int port) { int statsd_send_metric(afl_state_t *afl) { char buff[MAX_STATSD_PACKET_SIZE] = {0}; - /* Default port and host. - Will be overwritten by AFL_STATSD_PORT and AFL_STATSD_HOST environment - variable, if they exists. - */ - u16 port = STATSD_DEFAULT_PORT; - char *host = STATSD_DEFAULT_HOST; - - if (afl->afl_env.afl_statsd_port) { port = atoi(afl->afl_env.afl_statsd_port); } - if (afl->afl_env.afl_statsd_host) { host = afl->afl_env.afl_statsd_host; } - /* statds_sock is a global variable. We set it once in the beginning and reuse - the socket. If the sendto later fail, we reset it to 0 to be able to recreate - it. + /* afl->statsd_sock is set once in the initialisation of afl-fuzz and reused each time + If the sendto later fail, we reset it to 0 to be able to recreates it. */ - if (!statds_sock) { + if (!afl->statsd_sock) { - statds_sock = statsd_socket_init(host, port); - if (!statds_sock) { + afl->statsd_sock = statsd_socket_init(afl); + if (!afl->statsd_sock) { WARNF("Cannot create socket"); return -1; @@ -80,11 +75,11 @@ int statsd_send_metric(afl_state_t *afl) { } statsd_format_metric(afl, buff, MAX_STATSD_PACKET_SIZE); - if (sendto(statds_sock, buff, strlen(buff), 0, (struct sockaddr *)&server, - sizeof(server)) == -1) { + if (sendto(afl->statsd_sock, buff, strlen(buff), 0, (struct sockaddr *)&afl->statsd_server, + sizeof(afl->statsd_server)) == -1) { - if (!close(statds_sock)) { perror("Cannot close socket"); } - statds_sock = 0; + if (!close(afl->statsd_sock)) { perror("Cannot close socket"); } + afl->statsd_sock = 0; WARNF("Cannot sendto"); return -1; -- cgit v1.2.3 From 9ac9aa25111b67cd6a2ee7ce8376a445368b215f Mon Sep 17 00:00:00 2001 From: Edznux Date: Mon, 5 Oct 2020 22:21:24 +0200 Subject: Fix code format --- src/afl-fuzz-state.c | 1 + src/afl-fuzz-statsd.c | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index aefa226d..5e719a85 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -369,6 +369,7 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_statsd_host = (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_STATSD_PORT", afl_environment_variable_len)) { diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c index 0ec1bcb7..9cb8fde4 100644 --- a/src/afl-fuzz-statsd.c +++ b/src/afl-fuzz-statsd.c @@ -13,6 +13,7 @@ #define METRIC_PREFIX "fuzzing" int statsd_socket_init(afl_state_t *afl) { + /* Default port and host. Will be overwritten by AFL_STATSD_PORT and AFL_STATSD_HOST environment variable, if they exists. @@ -20,7 +21,12 @@ int statsd_socket_init(afl_state_t *afl) { u16 port = STATSD_DEFAULT_PORT; char *host = STATSD_DEFAULT_HOST; - if (afl->afl_env.afl_statsd_port) { port = atoi(afl->afl_env.afl_statsd_port); } + if (afl->afl_env.afl_statsd_port) { + + port = atoi(afl->afl_env.afl_statsd_port); + + } + if (afl->afl_env.afl_statsd_host) { host = afl->afl_env.afl_statsd_host; } int sock; @@ -47,7 +53,8 @@ int statsd_socket_init(afl_state_t *afl) { } - memcpy(&(afl->statsd_server.sin_addr), &((struct sockaddr_in *)result->ai_addr)->sin_addr, + memcpy(&(afl->statsd_server.sin_addr), + &((struct sockaddr_in *)result->ai_addr)->sin_addr, sizeof(struct in_addr)); freeaddrinfo(result); @@ -59,8 +66,9 @@ int statsd_send_metric(afl_state_t *afl) { char buff[MAX_STATSD_PACKET_SIZE] = {0}; - /* afl->statsd_sock is set once in the initialisation of afl-fuzz and reused each time - If the sendto later fail, we reset it to 0 to be able to recreates it. + /* afl->statsd_sock is set once in the initialisation of afl-fuzz and reused + each time If the sendto later fail, we reset it to 0 to be able to recreates + it. */ if (!afl->statsd_sock) { @@ -75,7 +83,8 @@ int statsd_send_metric(afl_state_t *afl) { } statsd_format_metric(afl, buff, MAX_STATSD_PACKET_SIZE); - if (sendto(afl->statsd_sock, buff, strlen(buff), 0, (struct sockaddr *)&afl->statsd_server, + if (sendto(afl->statsd_sock, buff, strlen(buff), 0, + (struct sockaddr *)&afl->statsd_server, sizeof(afl->statsd_server)) == -1) { if (!close(afl->statsd_sock)) { perror("Cannot close socket"); } -- cgit v1.2.3 From fd4efd04a1d55b070934e5307b8dd8f81aa8e8ac Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 5 Oct 2020 23:07:22 +0200 Subject: fixed gcc 10 warning --- src/afl-fuzz-stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 1d5b169d..654d9059 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -955,7 +955,7 @@ void show_stats(afl_state_t *afl) { #else SAYF("%s" cGRA " [cpu:%s%3u%%" cGRA "]\r" cRST, spacing, cpu_color, - MIN(cur_utilization, 999)); + MIN(cur_utilization, (u32)999)); #endif /* ^HAVE_AFFINITY */ -- cgit v1.2.3 From a4b60ca5b61c9bca5fa7b67528baeb3a8ea9320e Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 6 Oct 2020 15:37:59 +0200 Subject: testcase cache added --- src/afl-fuzz-one.c | 148 ++++++++++++++++++--------------------------------- src/afl-fuzz-queue.c | 65 ++++++++++++++++++++++ src/afl-fuzz.c | 3 +- 3 files changed, 119 insertions(+), 97 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index c04b492b..20558618 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -370,7 +370,7 @@ static void locate_diffs(u8 *ptr1, u8 *ptr2, u32 len, s32 *first, s32 *last) { u8 fuzz_one_original(afl_state_t *afl) { - s32 len, fd, temp_len; + s32 len, temp_len; u32 j; u32 i; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; @@ -453,28 +453,9 @@ u8 fuzz_one_original(afl_state_t *afl) { } - /* Map the test case into memory. */ - - fd = open(afl->queue_cur->fname, O_RDONLY); - - if (unlikely(fd < 0)) { - - PFATAL("Unable to open '%s'", afl->queue_cur->fname); - - } - + orig_in = in_buf = queue_testcase_take(afl, afl->queue_cur); len = afl->queue_cur->len; - orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - - if (unlikely(orig_in == MAP_FAILED)) { - - PFATAL("Unable to mmap '%s' with len %d", afl->queue_cur->fname, len); - - } - - close(fd); - /* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every single byte anyway, so it wouldn't give us any performance or memory usage benefits. */ @@ -1694,7 +1675,7 @@ custom_mutator_stage: for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { - struct queue_entry *target; + struct queue_entry *target = NULL; u32 tid; u8 * new_buf = NULL; u32 target_len = 0; @@ -1717,17 +1698,7 @@ custom_mutator_stage: afl->splicing_with = tid; /* Read the additional testcase into a new buffer. */ - fd = open(target->fname, O_RDONLY); - if (unlikely(fd < 0)) { - - PFATAL("Unable to open '%s'", target->fname); - - } - - new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), target->len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - ck_read(fd, new_buf, target->len, target->fname); - close(fd); + new_buf = queue_testcase_take(afl, target); target_len = target->len; } @@ -1738,6 +1709,11 @@ custom_mutator_stage: el->afl_custom_fuzz(el->data, out_buf, len, &mutated_buf, new_buf, target_len, max_seed_size); + if (new_buf) { + queue_testcase_release(afl, target); + new_buf = NULL; + } + if (unlikely(!mutated_buf)) { FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size); @@ -2320,51 +2296,44 @@ havoc_stage: /* Overwrite bytes with a randomly selected chunk from another testcase or insert that chunk. */ - if (afl->queued_paths < 4) break; + if (afl->queued_paths < 4) { break; } /* Pick a random queue entry and seek to it. */ u32 tid; - do + do { tid = rand_below(afl, afl->queued_paths); - while (tid == afl->current_entry); + } while (tid == afl->current_entry); struct queue_entry *target = afl->queue_buf[tid]; /* Make sure that the target has a reasonable length. */ - while (target && (target->len < 2 || target == afl->queue_cur)) + while (target && (target->len < 2 || target == afl->queue_cur)) { target = target->next; + } - if (!target) break; - - /* Read the testcase into a new buffer. */ - - fd = open(target->fname, O_RDONLY); - - if (unlikely(fd < 0)) { + if (!target) { break; } - PFATAL("Unable to open '%s'", target->fname); - - } u32 new_len = target->len; - u8 *new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), new_len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - - ck_read(fd, new_buf, new_len, target->fname); - close(fd); + /* Get the testcase contents for splicing. */ + u8 *new_buf = queue_testcase_take(afl, target); u8 overwrite = 0; - if (temp_len >= 2 && rand_below(afl, 2)) + if (temp_len >= 2 && rand_below(afl, 2)) { overwrite = 1; + } else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { - if (temp_len >= 2) + if (temp_len >= 2) { overwrite = 1; - else + } else { + queue_testcase_release(afl, target); + new_buf = NULL; break; + } } @@ -2411,6 +2380,9 @@ havoc_stage: } + /* We don't need this splice testcase anymore */ + queue_testcase_release(afl, target); + new_buf = NULL; break; } @@ -2516,24 +2488,16 @@ retry_splicing: if (!target) { goto retry_splicing; } - /* Read the testcase into a new buffer. */ - - fd = open(target->fname, O_RDONLY); - - if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); } - + /* Get the testcase buffer */ + u8 *splice_buf = queue_testcase_take(afl, target); new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); if (unlikely(!new_buf)) { PFATAL("alloc"); } - ck_read(fd, new_buf, target->len, target->fname); - - close(fd); - /* Find a suitable splicing location, somewhere between the first and the last differing byte. Bail out if the difference is just a single byte or so. */ - locate_diffs(in_buf, new_buf, MIN(len, (s64)target->len), &f_diff, &l_diff); + locate_diffs(in_buf, splice_buf, MIN(len, (s64)target->len), &f_diff, &l_diff); if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { goto retry_splicing; } @@ -2545,6 +2509,7 @@ retry_splicing: len = target->len; memcpy(new_buf, in_buf, split_at); + memcpy(new_buf + split_at, splice_buf + split_at, target->len - split_at); afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); in_buf = new_buf; @@ -2552,6 +2517,9 @@ retry_splicing: if (unlikely(!out_buf)) { PFATAL("alloc"); } memcpy(out_buf, in_buf, len); + queue_testcase_release(afl, target); + splice_buf = NULL; + goto custom_mutator_stage; /* ???: While integrating Python module, the author decided to jump to python stage, but the reason behind this is not clear.*/ @@ -2582,7 +2550,8 @@ abandon_entry: ++afl->queue_cur->fuzz_level; - munmap(orig_in, afl->queue_cur->len); + queue_testcase_release(afl, afl->queue_cur); + orig_in = NULL; return ret_val; @@ -2604,7 +2573,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { } - s32 len, fd, temp_len; + s32 len, temp_len; u32 i; u32 j; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; @@ -2669,23 +2638,9 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { } /* Map the test case into memory. */ - - fd = open(afl->queue_cur->fname, O_RDONLY); - - if (fd < 0) { PFATAL("Unable to open '%s'", afl->queue_cur->fname); } - + orig_in = in_buf = queue_testcase_take(afl, afl->queue_cur); len = afl->queue_cur->len; - orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - - if (orig_in == MAP_FAILED) { - - PFATAL("Unable to mmap '%s'", afl->queue_cur->fname); - - } - - close(fd); - /* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every single byte anyway, so it wouldn't give us any performance or memory usage benefits. */ @@ -4522,31 +4477,24 @@ pacemaker_fuzzing: if (!target) { goto retry_splicing_puppet; } /* Read the testcase into a new buffer. */ - - fd = open(target->fname, O_RDONLY); - - if (fd < 0) { PFATAL("Unable to open '%s'", target->fname); } - - new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - - ck_read(fd, new_buf, target->len, target->fname); - - close(fd); + u8 *splicing_buf = queue_testcase_take(afl, target); /* Find a suitable splicin g location, somewhere between the first and the last differing byte. Bail out if the difference is just a single byte or so. */ - locate_diffs(in_buf, new_buf, MIN(len, (s32)target->len), &f_diff, + locate_diffs(in_buf, splicing_buf, MIN(len, (s32)target->len), &f_diff, &l_diff); if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { + queue_testcase_release(afl, target); goto retry_splicing_puppet; } + new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); + /* Split somewhere between the first and last differing byte. */ split_at = f_diff + rand_below(afl, l_diff - f_diff); @@ -4555,12 +4503,16 @@ pacemaker_fuzzing: len = target->len; memcpy(new_buf, in_buf, split_at); + memcpy(new_buf + split_at, splicing_buf + split_at, target->len - split_at); afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); in_buf = new_buf; out_buf = afl_realloc(AFL_BUF_PARAM(out), len); if (unlikely(!out_buf)) { PFATAL("alloc"); } memcpy(out_buf, in_buf, len); + queue_testcase_release(afl, target); + splicing_buf = NULL; + goto havoc_stage_puppet; } /* if splice_cycle */ @@ -4594,7 +4546,8 @@ pacemaker_fuzzing: // if (afl->queue_cur->favored) --afl->pending_favored; // } - munmap(orig_in, afl->queue_cur->len); + queue_testcase_release(afl, afl->queue_cur); + orig_in = NULL; if (afl->key_puppet == 1) { @@ -4730,6 +4683,9 @@ pacemaker_fuzzing: } /* block */ + queue_testcase_release(afl, afl->queue_cur); + orig_in = NULL; + return ret_val; } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 0d7d0314..e2387aaa 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -220,6 +220,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { q->depth = afl->cur_depth + 1; q->passed_det = passed_det; q->trace_mini = NULL; + q->testcase_buf = NULL; if (q->depth > afl->max_depth) { afl->max_depth = q->depth; } @@ -767,3 +768,67 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { } +/* Tell afl that this testcase may be evicted from the cache */ +inline void queue_testcase_release(afl_state_t *afl, struct queue_entry *q) { + (void) afl; + q->testcase_refs--; + if (unlikely(q->testcase_refs < 0)) { FATAL("Testcase refcount smaller than 0"); } +} + +/* Returns the testcase buf from the file behind this queue entry. + Increases the refcount. */ +u8 *queue_testcase_take(afl_state_t *afl, struct queue_entry *q) { + if (!q->testcase_buf) { + u32 tid = 0; + /* Buf not cached, let's do that now */ + + if (likely(afl->q_testcase_cache_count == TESTCASE_CACHE_SIZE)) { + /* Cache full. We neet to evict one to map one. + Get a random one which is not in use */ + do { + + tid = rand_below(afl, afl->q_testcase_cache_count); + + } while (afl->q_testcase_cache[tid]->testcase_refs > 0); + + struct queue_entry *old_cached = afl->q_testcase_cache[tid]; + /* free the current buf from cache */ + munmap(old_cached->testcase_buf, old_cached->len); + old_cached->testcase_buf = NULL; + + } else { + tid = afl->q_testcase_cache_count; + afl->q_testcase_cache_count++; + } + + /* Map the test case into memory. */ + + int fd = open(q->fname, O_RDONLY); + + if (unlikely(fd < 0)) { + + PFATAL("Unable to open '%s'", q->fname); + + } + + u32 len = q->len; + + q->testcase_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + + if (unlikely(q->testcase_buf == MAP_FAILED)) { + + PFATAL("Unable to mmap '%s' with len %d", q->fname, len); + + } + + close(fd); + + /* Register us as cached */ + afl->q_testcase_cache[tid] = q; + + } + q->testcase_refs++; + if (!q->testcase_buf) { FATAL("Testcase buf is NULL, this should never happen"); } + return q->testcase_buf; + +} diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 2f8aa3fd..dd9aaa8f 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1152,8 +1152,9 @@ int main(int argc, char **argv_orig, char **envp) { if (extras_dir_cnt) { - for (i = 0; i < extras_dir_cnt; i++) + for (i = 0; i < extras_dir_cnt; i++) { load_extras(afl, extras_dir[i]); + } dedup_extras(afl); OKF("Loaded a total of %u extras.", afl->extras_cnt); -- cgit v1.2.3 From 74dc227c4412d0121c9b972e5d89db89f54c6b3a Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 6 Oct 2020 15:38:36 +0200 Subject: code format --- src/afl-fuzz-one.c | 22 +++++++++++++++++----- src/afl-fuzz-queue.c | 34 ++++++++++++++++++++++++---------- src/afl-fuzz.c | 2 ++ 3 files changed, 43 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 20558618..a5f77f11 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1710,8 +1710,10 @@ custom_mutator_stage: target_len, max_seed_size); if (new_buf) { + queue_testcase_release(afl, target); new_buf = NULL; + } if (unlikely(!mutated_buf)) { @@ -2302,7 +2304,9 @@ havoc_stage: u32 tid; do { + tid = rand_below(afl, afl->queued_paths); + } while (tid == afl->current_entry); struct queue_entry *target = afl->queue_buf[tid]; @@ -2310,12 +2314,13 @@ havoc_stage: /* Make sure that the target has a reasonable length. */ while (target && (target->len < 2 || target == afl->queue_cur)) { + target = target->next; + } if (!target) { break; } - u32 new_len = target->len; /* Get the testcase contents for splicing. */ @@ -2323,16 +2328,21 @@ havoc_stage: u8 overwrite = 0; if (temp_len >= 2 && rand_below(afl, 2)) { + overwrite = 1; - } - else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { + + } else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { if (temp_len >= 2) { + overwrite = 1; + } else { + queue_testcase_release(afl, target); new_buf = NULL; break; + } } @@ -2497,7 +2507,8 @@ retry_splicing: the last differing byte. Bail out if the difference is just a single byte or so. */ - locate_diffs(in_buf, splice_buf, MIN(len, (s64)target->len), &f_diff, &l_diff); + locate_diffs(in_buf, splice_buf, MIN(len, (s64)target->len), &f_diff, + &l_diff); if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { goto retry_splicing; } @@ -4503,7 +4514,8 @@ pacemaker_fuzzing: len = target->len; memcpy(new_buf, in_buf, split_at); - memcpy(new_buf + split_at, splicing_buf + split_at, target->len - split_at); + memcpy(new_buf + split_at, splicing_buf + split_at, + target->len - split_at); afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); in_buf = new_buf; out_buf = afl_realloc(AFL_BUF_PARAM(out), len); diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index e2387aaa..721f9ac7 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -770,24 +770,33 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { /* Tell afl that this testcase may be evicted from the cache */ inline void queue_testcase_release(afl_state_t *afl, struct queue_entry *q) { - (void) afl; + + (void)afl; q->testcase_refs--; - if (unlikely(q->testcase_refs < 0)) { FATAL("Testcase refcount smaller than 0"); } + if (unlikely(q->testcase_refs < 0)) { + + FATAL("Testcase refcount smaller than 0"); + + } + } /* Returns the testcase buf from the file behind this queue entry. Increases the refcount. */ u8 *queue_testcase_take(afl_state_t *afl, struct queue_entry *q) { + if (!q->testcase_buf) { + u32 tid = 0; /* Buf not cached, let's do that now */ if (likely(afl->q_testcase_cache_count == TESTCASE_CACHE_SIZE)) { + /* Cache full. We neet to evict one to map one. Get a random one which is not in use */ do { - tid = rand_below(afl, afl->q_testcase_cache_count); + tid = rand_below(afl, afl->q_testcase_cache_count); } while (afl->q_testcase_cache[tid]->testcase_refs > 0); @@ -795,21 +804,19 @@ u8 *queue_testcase_take(afl_state_t *afl, struct queue_entry *q) { /* free the current buf from cache */ munmap(old_cached->testcase_buf, old_cached->len); old_cached->testcase_buf = NULL; - + } else { + tid = afl->q_testcase_cache_count; afl->q_testcase_cache_count++; + } /* Map the test case into memory. */ int fd = open(q->fname, O_RDONLY); - if (unlikely(fd < 0)) { - - PFATAL("Unable to open '%s'", q->fname); - - } + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); } u32 len = q->len; @@ -827,8 +834,15 @@ u8 *queue_testcase_take(afl_state_t *afl, struct queue_entry *q) { afl->q_testcase_cache[tid] = q; } + q->testcase_refs++; - if (!q->testcase_buf) { FATAL("Testcase buf is NULL, this should never happen"); } + if (!q->testcase_buf) { + + FATAL("Testcase buf is NULL, this should never happen"); + + } + return q->testcase_buf; } + diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index dd9aaa8f..9b7c1445 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1153,7 +1153,9 @@ int main(int argc, char **argv_orig, char **envp) { if (extras_dir_cnt) { for (i = 0; i < extras_dir_cnt; i++) { + load_extras(afl, extras_dir[i]); + } dedup_extras(afl); -- cgit v1.2.3 From 4f207b4eba26c2b268ba2fd0a51298d6ab88f110 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 6 Oct 2020 16:20:32 +0200 Subject: fixed ref check --- src/afl-fuzz-queue.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 721f9ac7..58e026f5 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -772,13 +772,14 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { inline void queue_testcase_release(afl_state_t *afl, struct queue_entry *q) { (void)afl; - q->testcase_refs--; - if (unlikely(q->testcase_refs < 0)) { + if (unlikely(q->testcase_refs == 0)) { - FATAL("Testcase refcount smaller than 0"); + FATAL("Testcase refcount reduced past 0"); } + q->testcase_refs--; + } /* Returns the testcase buf from the file behind this queue entry. -- cgit v1.2.3 From 2d5fadc1e6a684b5e3e527a64b614f6b1ba8415f Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 6 Oct 2020 16:45:25 +0200 Subject: hunting ref underflow --- src/afl-fuzz-one.c | 3 --- src/afl-fuzz-queue.c | 11 +++++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index a5f77f11..f25ab4ee 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -4695,9 +4695,6 @@ pacemaker_fuzzing: } /* block */ - queue_testcase_release(afl, afl->queue_cur); - orig_in = NULL; - return ret_val; } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 58e026f5..0b491202 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -837,10 +837,17 @@ u8 *queue_testcase_take(afl_state_t *afl, struct queue_entry *q) { } q->testcase_refs++; - if (!q->testcase_buf) { + if (unlikely(!q->testcase_buf || !q->testcase_refs)) { + if (!q->testcase_buf) { + + FATAL("Testcase buf is NULL, this should never happen"); - FATAL("Testcase buf is NULL, this should never happen"); + } + if (!q->testcase_refs) { + FATAL("Testcase ref overflow. Missing a testcase release somwhere?"); + + } } return q->testcase_buf; -- cgit v1.2.3 From 3d7bdc9f0b6892cb359fc07a0cef387851cbd8b1 Mon Sep 17 00:00:00 2001 From: Edznux Date: Tue, 6 Oct 2020 23:00:11 +0200 Subject: [WIP: segfault on non dogstatsd] Adding MACROS for format --- src/afl-fuzz-state.c | 7 +++ src/afl-fuzz-statsd.c | 140 +++++++++++++++++++++++++++++++++++++------------- src/afl-fuzz.c | 5 ++ 3 files changed, 117 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 5e719a85..77b30b5b 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -377,6 +377,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_statsd_port = (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_STATSD_TAGS_FLAVOR", + + afl_environment_variable_len)) { + + afl->afl_env.afl_statsd_tags_flavor = + (u8 *)get_afl_env(afl_environment_variables[i]); + } } else { diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c index 9cb8fde4..f77df17e 100644 --- a/src/afl-fuzz-statsd.c +++ b/src/afl-fuzz-statsd.c @@ -12,6 +12,107 @@ #define MAX_TAG_LEN 200 #define METRIC_PREFIX "fuzzing" +/* Tags format for metrics + DogStatsD: + metric.name:||#key:value,key2:value2 + + InfluxDB + metric.name,key=value,key2=value2:| + + Librato + metric.name#key=value,key2=value2:| + + SignalFX + metric.name[key=value,key2=value2]:| + +*/ + +// after the whole metric. +#define DOGSTATSD_TAGS_FORMAT "|#banner:%s,afl_version:%s" + +// just after the metric name. +#define LIBRATO_TAGS_FORMAT "#banner=%s,afl_version=%s" +#define INFLUXDB_TAGS_FORMAT ",banner=%s,afl_version=%s" +#define SIGNALFX_TAGS_FORMAT "[banner=%s,afl_version=%s]" + +// For DogstatsD +#define STATSD_TAGS_AFTER_METRICS \ + METRIC_PREFIX \ + ".cycle_done:%llu|g%s\n" METRIC_PREFIX \ + ".cycles_wo_finds:%llu|g%s\n" METRIC_PREFIX \ + ".execs_done:%llu|g%s\n" METRIC_PREFIX \ + ".execs_per_sec:%0.02f|g%s\n" METRIC_PREFIX \ + ".paths_total:%u|g%s\n" METRIC_PREFIX \ + ".paths_favored:%u|g%s\n" METRIC_PREFIX \ + ".paths_found:%u|g%s\n" METRIC_PREFIX \ + ".paths_imported:%u|g%s\n" METRIC_PREFIX \ + ".max_depth:%u|g%s\n" METRIC_PREFIX ".cur_path:%u|g%s\n" METRIC_PREFIX \ + ".pending_favs:%u|g%s\n" METRIC_PREFIX \ + ".pending_total:%u|g%s\n" METRIC_PREFIX \ + ".variable_paths:%u|g%s\n" METRIC_PREFIX \ + ".unique_crashes:%llu|g%s\n" METRIC_PREFIX \ + ".unique_hangs:%llu|g%s\n" METRIC_PREFIX \ + ".total_crashes:%llu|g%s\n" METRIC_PREFIX \ + ".slowest_exec_ms:%u|g%s\n" METRIC_PREFIX \ + ".edges_found:%u|g%s\n" METRIC_PREFIX \ + ".var_byte_count:%u|g%s\n" METRIC_PREFIX ".havoc_expansion:%u|g%s\n" + +// For Librato, InfluxDB, SignalFX +#define STATSD_TAGS_MID_METRICS \ + METRIC_PREFIX \ + ".cycle_done%s:%llu|g\n" METRIC_PREFIX \ + ".cycles_wo_finds%s:%llu|g\n" METRIC_PREFIX \ + ".execs_done%s:%llu|g\n" METRIC_PREFIX \ + ".execs_per_sec%s:%0.02f|g\n" METRIC_PREFIX \ + ".paths_total%s:%u|g\n" METRIC_PREFIX \ + ".paths_favored%s:%u|g\n" METRIC_PREFIX \ + ".paths_found%s:%u|g\n" METRIC_PREFIX \ + ".paths_imported%s:%u|g\n" METRIC_PREFIX \ + ".max_depth%s:%u|g\n" METRIC_PREFIX ".cur_path%s:%u|g\n" METRIC_PREFIX \ + ".pending_favs%s:%u|g\n" METRIC_PREFIX \ + ".pending_total%s:%u|g\n" METRIC_PREFIX \ + ".variable_paths%s:%u|g\n" METRIC_PREFIX \ + ".unique_crashes%s:%llu|g\n" METRIC_PREFIX \ + ".unique_hangs%s:%llu|g\n" METRIC_PREFIX \ + ".total_crashes%s:%llu|g\n" METRIC_PREFIX \ + ".slowest_exec_ms%s:%u|g\n" METRIC_PREFIX \ + ".edges_found%s:%u|g\n" METRIC_PREFIX \ + ".var_byte_count%s:%u|g\n" METRIC_PREFIX ".havoc_expansion%s:%u|g\n" + +void statsd_setup_format(afl_state_t *afl) { + + if (strcmp(afl->afl_env.afl_statsd_tags_flavor, "dogstatsd") == 0) { + + afl->statsd_tags_format = DOGSTATSD_TAGS_FORMAT; + afl->statsd_metric_format = STATSD_TAGS_AFTER_METRICS; + + } else if (strcmp(afl->afl_env.afl_statsd_tags_flavor, "librato") == 0) { + + afl->statsd_tags_format = LIBRATO_TAGS_FORMAT; + afl->statsd_metric_format = STATSD_TAGS_MID_METRICS; + + } else if (strcmp(afl->afl_env.afl_statsd_tags_flavor, "influxdb") == 0) { + + afl->statsd_tags_format = INFLUXDB_TAGS_FORMAT; + afl->statsd_metric_format = STATSD_TAGS_MID_METRICS; + + } else if (strcmp(afl->afl_env.afl_statsd_tags_flavor, "signalfx") == 0) { + + afl->statsd_tags_format = SIGNALFX_TAGS_FORMAT; + afl->statsd_metric_format = STATSD_TAGS_MID_METRICS; + + } else { + + // No tags at all. + afl->statsd_tags_format = ""; + // Still need to pick a format. Doesn't change anything since if will be + // replaced by the empty string anyway. + afl->statsd_metric_format = STATSD_TAGS_MID_METRICS; + + } + +} + int statsd_socket_init(afl_state_t *afl) { /* Default port and host. @@ -87,7 +188,7 @@ int statsd_send_metric(afl_state_t *afl) { (struct sockaddr *)&afl->statsd_server, sizeof(afl->statsd_server)) == -1) { - if (!close(afl->statsd_sock)) { perror("Cannot close socket"); } + if (!close(afl->statsd_sock)) { FATAL("Cannot close socket"); } afl->statsd_sock = 0; WARNF("Cannot sendto"); return -1; @@ -100,45 +201,14 @@ int statsd_send_metric(afl_state_t *afl) { int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen) { -/* Metric format: -:| -*/ -#ifdef USE_DOGSTATSD_TAGS - /* Tags format: DogStatsD - :||#key:value,key:value,key - */ char tags[MAX_TAG_LEN * 2] = {0}; - snprintf(tags, MAX_TAG_LEN * 2, "|#banner:%s,afl_version:%s", afl->use_banner, + snprintf(tags, MAX_TAG_LEN * 2, afl->statsd_tags_format, afl->use_banner, VERSION); -#else - /* No tags. - */ - char *tags = ""; -#endif + /* Sends multiple metrics with one UDP Packet. bufflen will limit to the max safe size. */ - snprintf(buff, bufflen, - METRIC_PREFIX ".cycle_done:%llu|g%s\n" METRIC_PREFIX - ".cycles_wo_finds:%llu|g%s\n" METRIC_PREFIX - ".execs_done:%llu|g%s\n" METRIC_PREFIX - ".execs_per_sec:%0.02f|g%s\n" METRIC_PREFIX - ".paths_total:%u|g%s\n" METRIC_PREFIX - ".paths_favored:%u|g%s\n" METRIC_PREFIX - ".paths_found:%u|g%s\n" METRIC_PREFIX - ".paths_imported:%u|g%s\n" METRIC_PREFIX - ".max_depth:%u|g%s\n" METRIC_PREFIX - ".cur_path:%u|g%s\n" METRIC_PREFIX - ".pending_favs:%u|g%s\n" METRIC_PREFIX - ".pending_total:%u|g%s\n" METRIC_PREFIX - ".variable_paths:%u|g%s\n" METRIC_PREFIX - ".unique_crashes:%llu|g%s\n" METRIC_PREFIX - ".unique_hangs:%llu|g%s\n" METRIC_PREFIX - ".total_crashes:%llu|g%s\n" METRIC_PREFIX - ".slowest_exec_ms:%u|g%s\n" METRIC_PREFIX - ".edges_found:%u|g%s\n" METRIC_PREFIX - ".var_byte_count:%u|g%s\n" METRIC_PREFIX - ".havoc_expansion:%u|g%s\n", + snprintf(buff, bufflen, afl->statsd_metric_format, afl->queue_cycle ? (afl->queue_cycle - 1) : 0, tags, afl->cycles_wo_finds, tags, afl->fsrv.total_execs, tags, afl->fsrv.total_execs / diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 0b08f426..e0e9487f 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -891,6 +891,11 @@ int main(int argc, char **argv_orig, char **envp) { } + #ifdef USE_STATSD + statsd_setup_format(afl); + statsd_socket_init(afl); + #endif + if (strchr(argv[optind], '/') == NULL && !afl->unicorn_mode) { WARNF(cLRD -- cgit v1.2.3 From 17abe7d36e1bf63e149b3c0be20d3d0b7076746f Mon Sep 17 00:00:00 2001 From: Edznux Date: Tue, 6 Oct 2020 23:23:45 +0200 Subject: Fixed segfault because wrong order in args --- src/afl-fuzz-statsd.c | 137 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c index f77df17e..e6640977 100644 --- a/src/afl-fuzz-statsd.c +++ b/src/afl-fuzz-statsd.c @@ -36,70 +36,74 @@ #define SIGNALFX_TAGS_FORMAT "[banner=%s,afl_version=%s]" // For DogstatsD -#define STATSD_TAGS_AFTER_METRICS \ - METRIC_PREFIX \ - ".cycle_done:%llu|g%s\n" METRIC_PREFIX \ - ".cycles_wo_finds:%llu|g%s\n" METRIC_PREFIX \ - ".execs_done:%llu|g%s\n" METRIC_PREFIX \ - ".execs_per_sec:%0.02f|g%s\n" METRIC_PREFIX \ - ".paths_total:%u|g%s\n" METRIC_PREFIX \ - ".paths_favored:%u|g%s\n" METRIC_PREFIX \ - ".paths_found:%u|g%s\n" METRIC_PREFIX \ - ".paths_imported:%u|g%s\n" METRIC_PREFIX \ - ".max_depth:%u|g%s\n" METRIC_PREFIX ".cur_path:%u|g%s\n" METRIC_PREFIX \ - ".pending_favs:%u|g%s\n" METRIC_PREFIX \ - ".pending_total:%u|g%s\n" METRIC_PREFIX \ - ".variable_paths:%u|g%s\n" METRIC_PREFIX \ - ".unique_crashes:%llu|g%s\n" METRIC_PREFIX \ - ".unique_hangs:%llu|g%s\n" METRIC_PREFIX \ - ".total_crashes:%llu|g%s\n" METRIC_PREFIX \ - ".slowest_exec_ms:%u|g%s\n" METRIC_PREFIX \ - ".edges_found:%u|g%s\n" METRIC_PREFIX \ - ".var_byte_count:%u|g%s\n" METRIC_PREFIX ".havoc_expansion:%u|g%s\n" +#define STATSD_TAGS_TYPE_SUFFIX 1 +#define STATSD_TAGS_SUFFIX_METRICS \ + METRIC_PREFIX \ + ".cycle_done:%llu|g%s\n" METRIC_PREFIX \ + ".cycles_wo_finds:%llu|g%s\n" METRIC_PREFIX \ + ".execs_done:%llu|g%s\n" METRIC_PREFIX \ + ".execs_per_sec:%0.02f|g%s\n" METRIC_PREFIX \ + ".paths_total:%u|g%s\n" METRIC_PREFIX \ + ".paths_favored:%u|g%s\n" METRIC_PREFIX \ + ".paths_found:%u|g%s\n" METRIC_PREFIX \ + ".paths_imported:%u|g%s\n" METRIC_PREFIX ".max_depth:%u|g%s\n" METRIC_PREFIX \ + ".cur_path:%u|g%s\n" METRIC_PREFIX ".pending_favs:%u|g%s\n" METRIC_PREFIX \ + ".pending_total:%u|g%s\n" METRIC_PREFIX \ + ".variable_paths:%u|g%s\n" METRIC_PREFIX \ + ".unique_crashes:%llu|g%s\n" METRIC_PREFIX \ + ".unique_hangs:%llu|g%s\n" METRIC_PREFIX \ + ".total_crashes:%llu|g%s\n" METRIC_PREFIX \ + ".slowest_exec_ms:%u|g%s\n" METRIC_PREFIX \ + ".edges_found:%u|g%s\n" METRIC_PREFIX \ + ".var_byte_count:%u|g%s\n" METRIC_PREFIX ".havoc_expansion:%u|g%s\n" // For Librato, InfluxDB, SignalFX -#define STATSD_TAGS_MID_METRICS \ - METRIC_PREFIX \ - ".cycle_done%s:%llu|g\n" METRIC_PREFIX \ - ".cycles_wo_finds%s:%llu|g\n" METRIC_PREFIX \ - ".execs_done%s:%llu|g\n" METRIC_PREFIX \ - ".execs_per_sec%s:%0.02f|g\n" METRIC_PREFIX \ - ".paths_total%s:%u|g\n" METRIC_PREFIX \ - ".paths_favored%s:%u|g\n" METRIC_PREFIX \ - ".paths_found%s:%u|g\n" METRIC_PREFIX \ - ".paths_imported%s:%u|g\n" METRIC_PREFIX \ - ".max_depth%s:%u|g\n" METRIC_PREFIX ".cur_path%s:%u|g\n" METRIC_PREFIX \ - ".pending_favs%s:%u|g\n" METRIC_PREFIX \ - ".pending_total%s:%u|g\n" METRIC_PREFIX \ - ".variable_paths%s:%u|g\n" METRIC_PREFIX \ - ".unique_crashes%s:%llu|g\n" METRIC_PREFIX \ - ".unique_hangs%s:%llu|g\n" METRIC_PREFIX \ - ".total_crashes%s:%llu|g\n" METRIC_PREFIX \ - ".slowest_exec_ms%s:%u|g\n" METRIC_PREFIX \ - ".edges_found%s:%u|g\n" METRIC_PREFIX \ - ".var_byte_count%s:%u|g\n" METRIC_PREFIX ".havoc_expansion%s:%u|g\n" +#define STATSD_TAGS_TYPE_MID 2 +#define STATSD_TAGS_MID_METRICS \ + METRIC_PREFIX \ + ".cycle_done%s:%llu|g\n" METRIC_PREFIX \ + ".cycles_wo_finds%s:%llu|g\n" METRIC_PREFIX \ + ".execs_done%s:%llu|g\n" METRIC_PREFIX \ + ".execs_per_sec%s:%0.02f|g\n" METRIC_PREFIX \ + ".paths_total%s:%u|g\n" METRIC_PREFIX \ + ".paths_favored%s:%u|g\n" METRIC_PREFIX \ + ".paths_found%s:%u|g\n" METRIC_PREFIX \ + ".paths_imported%s:%u|g\n" METRIC_PREFIX ".max_depth%s:%u|g\n" METRIC_PREFIX \ + ".cur_path%s:%u|g\n" METRIC_PREFIX ".pending_favs%s:%u|g\n" METRIC_PREFIX \ + ".pending_total%s:%u|g\n" METRIC_PREFIX \ + ".variable_paths%s:%u|g\n" METRIC_PREFIX \ + ".unique_crashes%s:%llu|g\n" METRIC_PREFIX \ + ".unique_hangs%s:%llu|g\n" METRIC_PREFIX \ + ".total_crashes%s:%llu|g\n" METRIC_PREFIX \ + ".slowest_exec_ms%s:%u|g\n" METRIC_PREFIX \ + ".edges_found%s:%u|g\n" METRIC_PREFIX \ + ".var_byte_count%s:%u|g\n" METRIC_PREFIX ".havoc_expansion%s:%u|g\n" void statsd_setup_format(afl_state_t *afl) { if (strcmp(afl->afl_env.afl_statsd_tags_flavor, "dogstatsd") == 0) { afl->statsd_tags_format = DOGSTATSD_TAGS_FORMAT; - afl->statsd_metric_format = STATSD_TAGS_AFTER_METRICS; + afl->statsd_metric_format = STATSD_TAGS_SUFFIX_METRICS; + afl->statsd_metric_format_type = STATSD_TAGS_TYPE_SUFFIX; } else if (strcmp(afl->afl_env.afl_statsd_tags_flavor, "librato") == 0) { afl->statsd_tags_format = LIBRATO_TAGS_FORMAT; afl->statsd_metric_format = STATSD_TAGS_MID_METRICS; + afl->statsd_metric_format_type = STATSD_TAGS_TYPE_MID; } else if (strcmp(afl->afl_env.afl_statsd_tags_flavor, "influxdb") == 0) { afl->statsd_tags_format = INFLUXDB_TAGS_FORMAT; afl->statsd_metric_format = STATSD_TAGS_MID_METRICS; + afl->statsd_metric_format_type = STATSD_TAGS_TYPE_MID; } else if (strcmp(afl->afl_env.afl_statsd_tags_flavor, "signalfx") == 0) { afl->statsd_tags_format = SIGNALFX_TAGS_FORMAT; afl->statsd_metric_format = STATSD_TAGS_MID_METRICS; + afl->statsd_metric_format_type = STATSD_TAGS_TYPE_MID; } else { @@ -108,6 +112,7 @@ void statsd_setup_format(afl_state_t *afl) { // Still need to pick a format. Doesn't change anything since if will be // replaced by the empty string anyway. afl->statsd_metric_format = STATSD_TAGS_MID_METRICS; + afl->statsd_metric_format_type = STATSD_TAGS_TYPE_MID; } @@ -188,7 +193,7 @@ int statsd_send_metric(afl_state_t *afl) { (struct sockaddr *)&afl->statsd_server, sizeof(afl->statsd_server)) == -1) { - if (!close(afl->statsd_sock)) { FATAL("Cannot close socket"); } + if (!close(afl->statsd_sock)) { PFATAL("Cannot close socket"); } afl->statsd_sock = 0; WARNF("Cannot sendto"); return -1; @@ -208,19 +213,41 @@ int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen) { /* Sends multiple metrics with one UDP Packet. bufflen will limit to the max safe size. */ - snprintf(buff, bufflen, afl->statsd_metric_format, - afl->queue_cycle ? (afl->queue_cycle - 1) : 0, tags, - afl->cycles_wo_finds, tags, afl->fsrv.total_execs, tags, - afl->fsrv.total_execs / - ((double)(get_cur_time() - afl->start_time) / 1000), - tags, afl->queued_paths, tags, afl->queued_favored, tags, - afl->queued_discovered, tags, afl->queued_imported, tags, - afl->max_depth, tags, afl->current_entry, tags, afl->pending_favored, - tags, afl->pending_not_fuzzed, tags, afl->queued_variable, tags, - afl->unique_crashes, tags, afl->unique_hangs, tags, - afl->total_crashes, tags, afl->slowest_exec_ms, tags, - count_non_255_bytes(afl, afl->virgin_bits), tags, - afl->var_byte_count, tags, afl->expand_havoc, tags); + if (afl->statsd_metric_format_type == STATSD_TAGS_TYPE_SUFFIX) { + + snprintf(buff, bufflen, afl->statsd_metric_format, + afl->queue_cycle ? (afl->queue_cycle - 1) : 0, tags, + afl->cycles_wo_finds, tags, afl->fsrv.total_execs, tags, + afl->fsrv.total_execs / + ((double)(get_cur_time() - afl->start_time) / 1000), + tags, afl->queued_paths, tags, afl->queued_favored, tags, + afl->queued_discovered, tags, afl->queued_imported, tags, + afl->max_depth, tags, afl->current_entry, tags, + afl->pending_favored, tags, afl->pending_not_fuzzed, tags, + afl->queued_variable, tags, afl->unique_crashes, tags, + afl->unique_hangs, tags, afl->total_crashes, tags, + afl->slowest_exec_ms, tags, + count_non_255_bytes(afl, afl->virgin_bits), tags, + afl->var_byte_count, tags, afl->expand_havoc, tags); + + } else if (afl->statsd_metric_format_type == STATSD_TAGS_TYPE_MID) { + + snprintf(buff, bufflen, afl->statsd_metric_format, tags, + afl->queue_cycle ? (afl->queue_cycle - 1) : 0, tags, + afl->cycles_wo_finds, tags, afl->fsrv.total_execs, tags, + afl->fsrv.total_execs / + ((double)(get_cur_time() - afl->start_time) / 1000), + tags, afl->queued_paths, tags, afl->queued_favored, tags, + afl->queued_discovered, tags, afl->queued_imported, tags, + afl->max_depth, tags, afl->current_entry, tags, + afl->pending_favored, tags, afl->pending_not_fuzzed, tags, + afl->queued_variable, tags, afl->unique_crashes, tags, + afl->unique_hangs, tags, afl->total_crashes, tags, + afl->slowest_exec_ms, tags, + count_non_255_bytes(afl, afl->virgin_bits), tags, + afl->var_byte_count, tags, afl->expand_havoc); + + } return 0; -- cgit v1.2.3 From 3e16cf5fbf111b75e53abee91cca5202715eb411 Mon Sep 17 00:00:00 2001 From: Edznux Date: Wed, 7 Oct 2020 00:20:13 +0200 Subject: Remove statsd_socket_init, just let it init when doing the first iteration --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e0e9487f..0b38bdd8 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -893,7 +893,7 @@ int main(int argc, char **argv_orig, char **envp) { #ifdef USE_STATSD statsd_setup_format(afl); - statsd_socket_init(afl); + #endif if (strchr(argv[optind], '/') == NULL && !afl->unicorn_mode) { -- cgit v1.2.3 From 1fd2ffaf14efb3623ae01951ae0266e0f4f553f2 Mon Sep 17 00:00:00 2001 From: Edznux Date: Wed, 7 Oct 2020 00:51:31 +0200 Subject: Fix read on undefined char*. --- src/afl-fuzz-statsd.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c index e6640977..69cafd90 100644 --- a/src/afl-fuzz-statsd.c +++ b/src/afl-fuzz-statsd.c @@ -81,25 +81,32 @@ void statsd_setup_format(afl_state_t *afl) { - if (strcmp(afl->afl_env.afl_statsd_tags_flavor, "dogstatsd") == 0) { + if (afl->afl_env.afl_statsd_tags_flavor && + strcmp(afl->afl_env.afl_statsd_tags_flavor, "dogstatsd") == 0) { afl->statsd_tags_format = DOGSTATSD_TAGS_FORMAT; afl->statsd_metric_format = STATSD_TAGS_SUFFIX_METRICS; afl->statsd_metric_format_type = STATSD_TAGS_TYPE_SUFFIX; - } else if (strcmp(afl->afl_env.afl_statsd_tags_flavor, "librato") == 0) { + } else if (afl->afl_env.afl_statsd_tags_flavor && + + strcmp(afl->afl_env.afl_statsd_tags_flavor, "librato") == 0) { afl->statsd_tags_format = LIBRATO_TAGS_FORMAT; afl->statsd_metric_format = STATSD_TAGS_MID_METRICS; afl->statsd_metric_format_type = STATSD_TAGS_TYPE_MID; - } else if (strcmp(afl->afl_env.afl_statsd_tags_flavor, "influxdb") == 0) { + } else if (afl->afl_env.afl_statsd_tags_flavor && + + strcmp(afl->afl_env.afl_statsd_tags_flavor, "influxdb") == 0) { afl->statsd_tags_format = INFLUXDB_TAGS_FORMAT; afl->statsd_metric_format = STATSD_TAGS_MID_METRICS; afl->statsd_metric_format_type = STATSD_TAGS_TYPE_MID; - } else if (strcmp(afl->afl_env.afl_statsd_tags_flavor, "signalfx") == 0) { + } else if (afl->afl_env.afl_statsd_tags_flavor && + + strcmp(afl->afl_env.afl_statsd_tags_flavor, "signalfx") == 0) { afl->statsd_tags_format = SIGNALFX_TAGS_FORMAT; afl->statsd_metric_format = STATSD_TAGS_MID_METRICS; @@ -207,8 +214,12 @@ int statsd_send_metric(afl_state_t *afl) { int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen) { char tags[MAX_TAG_LEN * 2] = {0}; - snprintf(tags, MAX_TAG_LEN * 2, afl->statsd_tags_format, afl->use_banner, - VERSION); + if (afl->statsd_tags_format) { + + snprintf(tags, MAX_TAG_LEN * 2, afl->statsd_tags_format, afl->use_banner, + VERSION); + + } /* Sends multiple metrics with one UDP Packet. bufflen will limit to the max safe size. -- cgit v1.2.3 From c12b98e0a4a98200b43b01a9b0b721f8ca1e4dbf Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 7 Oct 2020 17:45:54 +0200 Subject: efficient queue jump --- src/afl-fuzz.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 2f8aa3fd..8458b50f 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1331,11 +1331,11 @@ int main(int argc, char **argv_orig, char **envp) { afl->cur_skipped_paths = 0; afl->queue_cur = afl->queue; - while (seek_to) { + if (seek_to) { - ++afl->current_entry; - --seek_to; - afl->queue_cur = afl->queue_cur->next; + afl->current_entry = seek_to; + afl->queue_cur = afl->queue_buf[seek_to]; + seek_to = 0; } -- cgit v1.2.3 From deab5a1532777df16aaf83bda2dc6cf757a8b49e Mon Sep 17 00:00:00 2001 From: Edznux Date: Wed, 7 Oct 2020 19:44:02 +0200 Subject: Add documentation/help for AFL_STATSD_TAGS_FLAVOR --- src/afl-fuzz.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 0b38bdd8..c26e53b9 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -196,6 +196,8 @@ static void usage(u8 *argv0, int more_help) { "AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n" "AFL_STATSD_HOST: change default statsd host. (default 127.0.0.1)" "AFL_STATSD_PORT: change default statsd port (default: 8125)" + "AFL_STATSD_TAGS_FLAVOR: change default statsd tags format (default will disable tags)." + " Supported formats are: 'dogstatsd', 'librato', 'signalfx' and 'influxdb'" "AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n" //"AFL_PERSISTENT: not supported anymore -> no effect, just a warning\n" //"AFL_DEFER_FORKSRV: not supported anymore -> no effect, just a warning\n" -- cgit v1.2.3 From 0220a8ff6670da2b9fd8cb883528d2a86f683c74 Mon Sep 17 00:00:00 2001 From: Edznux Date: Thu, 8 Oct 2020 20:48:46 +0200 Subject: Add env var toggle for StatsD --- src/afl-fuzz-state.c | 7 +++++++ src/afl-fuzz-stats.c | 15 ++++++++------- src/afl-fuzz.c | 8 +++----- 3 files changed, 18 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 77b30b5b..a7c7aff9 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -316,6 +316,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_cal_fast = get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_STATSD", + + afl_environment_variable_len)) { + + afl->afl_env.afl_statsd = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_TMPDIR", afl_environment_variable_len)) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 942670b4..0d6c6a66 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -423,16 +423,17 @@ void show_stats(afl_state_t *afl) { } -#ifdef USE_STATSD - if (cur_ms - afl->statsd_last_send_ms > STATSD_UPDATE_SEC * 1000) { + if (unlikely(afl->afl_env.afl_statsd == 1)) { - /* reset counter, even if send failed. */ - afl->statsd_last_send_ms = cur_ms; - if (statsd_send_metric(afl)) { WARNF("coundln't send statsd metric."); } + if (cur_ms - afl->statsd_last_send_ms > STATSD_UPDATE_SEC * 1000) { - } + /* reset counter, even if send failed. */ + afl->statsd_last_send_ms = cur_ms; + if (statsd_send_metric(afl)) { WARNF("coundln't send statsd metric."); } -#endif + } + + } /* Every now and then, write plot data. */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index c26e53b9..2c2f0ba5 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -194,7 +194,8 @@ static void usage(u8 *argv0, int more_help) { "AFL_SKIP_BIN_CHECK: skip the check, if the target is an executable\n" "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n" "AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n" - "AFL_STATSD_HOST: change default statsd host. (default 127.0.0.1)" + "AFL_STATSD: enables StatsD metrics collection" + "AFL_STATSD_HOST: change default statsd host (default 127.0.0.1)" "AFL_STATSD_PORT: change default statsd port (default: 8125)" "AFL_STATSD_TAGS_FLAVOR: change default statsd tags format (default will disable tags)." " Supported formats are: 'dogstatsd', 'librato', 'signalfx' and 'influxdb'" @@ -893,10 +894,7 @@ int main(int argc, char **argv_orig, char **envp) { } - #ifdef USE_STATSD - statsd_setup_format(afl); - - #endif + if (unlikely(afl->afl_env.afl_statsd == 1)) { statsd_setup_format(afl); } if (strchr(argv[optind], '/') == NULL && !afl->unicorn_mode) { -- cgit v1.2.3 From 4cb4772e2af9511c2320de833a81bc43500cef14 Mon Sep 17 00:00:00 2001 From: Edznux Date: Fri, 9 Oct 2020 18:58:27 +0200 Subject: Remove ==1 in the condition --- src/afl-fuzz-stats.c | 2 +- src/afl-fuzz.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 0d6c6a66..8a1c2cc6 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -423,7 +423,7 @@ void show_stats(afl_state_t *afl) { } - if (unlikely(afl->afl_env.afl_statsd == 1)) { + if (unlikely(afl->afl_env.afl_statsd)) { if (cur_ms - afl->statsd_last_send_ms > STATSD_UPDATE_SEC * 1000) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 2c2f0ba5..aa36a6c6 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -894,7 +894,7 @@ int main(int argc, char **argv_orig, char **envp) { } - if (unlikely(afl->afl_env.afl_statsd == 1)) { statsd_setup_format(afl); } + if (unlikely(afl->afl_env.afl_statsd)) { statsd_setup_format(afl); } if (strchr(argv[optind], '/') == NULL && !afl->unicorn_mode) { -- cgit v1.2.3 From 125f8b6ba71fba91735374b1bd07333b19aae635 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 9 Oct 2020 23:23:44 +0200 Subject: -m none is the default now --- src/afl-fuzz-state.c | 2 +- src/afl-fuzz.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 4a1e739f..a8e56e60 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -87,7 +87,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->w_end = 0.3; afl->g_max = 5000; afl->period_pilot_tmp = 5000.0; - afl->schedule = COE; /* Power schedule (default: COE) */ + afl->schedule = EXPLORE; /* Power schedule (default: EXPLORE) */ afl->havoc_max_mult = HAVOC_MAX_MULT; afl->clear_screen = 1; /* Window resized? */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 8458b50f..cf0a30c9 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -90,13 +90,13 @@ static void usage(u8 *argv0, int more_help) { "Execution control settings:\n" " -p schedule - power schedules compute a seed's performance score:\n" - " -- see docs/power_schedules.md\n" " -f file - location read by the fuzzed program (default: stdin " "or @@)\n" " -t msec - timeout for each run (auto-scaled, 50-%d ms)\n" - " -m megs - memory limit for child process (%d MB)\n" + " -m megs - memory limit for child process (%d MB, 0 = no limit)\n" " -Q - use binary-only instrumentation (QEMU mode)\n" " -U - use unicorn-based instrumentation (Unicorn mode)\n" " -W - use qemu-based instrumentation with Wine (Wine " -- cgit v1.2.3 From 5dc3bc175b664f0921ebd1265d4419d611aa4a74 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 10 Oct 2020 10:41:30 +0200 Subject: fix typo --- src/afl-fuzz-stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 0cd6f399..76f24977 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -429,7 +429,7 @@ void show_stats(afl_state_t *afl) { /* reset counter, even if send failed. */ afl->statsd_last_send_ms = cur_ms; - if (statsd_send_metric(afl)) { WARNF("coundln't send statsd metric."); } + if (statsd_send_metric(afl)) { WARNF("could not send statsd metric."); } } -- cgit v1.2.3 From 445aba9221471eebd7ffc2c35b97accd00b40557 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 10 Oct 2020 10:55:56 +0200 Subject: determinstic fuzzing is now disabled by default --- src/afl-fuzz-state.c | 2 ++ src/afl-fuzz.c | 7 +++---- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index b7d44dbf..a0a2795e 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -101,6 +101,8 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->hang_tmout = EXEC_TIMEOUT; afl->stats_update_freq = 1; afl->stats_avg_exec = -1; + afl->skip_deterministic = 1; + afl->use_splicing = 1; #ifdef HAVE_AFFINITY afl->cpu_aff = -1; /* Selected CPU core */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index dc0eb4a7..24df2997 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -103,6 +103,7 @@ static void usage(u8 *argv0, int more_help) { "mode)\n\n" "Mutator settings:\n" + " -D - enable deterministic fuzzing (once per queue entry)\n" " -L minutes - use MOpt(imize) mode and set the time limit for " "entering the\n" " pacemaker mode (minutes of no new paths). 0 = " @@ -116,7 +117,6 @@ static void usage(u8 *argv0, int more_help) { "Fuzzing behavior settings:\n" " -N - do not unlink the fuzzing input file (for devices " "etc.)\n" - " -d - quick & dirty mode (skips deterministic steps)\n" " -n - fuzz without instrumentation (non-instrumented mode)\n" " -x dict_file - fuzzer dictionary (see README.md, specify up to 4 " "times)\n\n" @@ -136,6 +136,7 @@ static void usage(u8 *argv0, int more_help) { " -F path - sync to a foreign fuzzer queue directory (requires " "-M, can\n" " be specified up to %u times)\n" + " -d - skip deterministic fuzzing in -M mode\n" " -T text - text banner to show on the screen\n" " -I command - execute this command/script when a new crash is " "found\n" @@ -403,6 +404,7 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); } afl->sync_id = ck_strdup(optarg); + afl->skip_deterministic = 0; if ((c = strchr(afl->sync_id, ':'))) { @@ -431,8 +433,6 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); } afl->sync_id = ck_strdup(optarg); afl->is_secondary_node = 1; - afl->skip_deterministic = 1; - afl->use_splicing = 1; break; case 'F': /* foreign sync dir */ @@ -557,7 +557,6 @@ int main(int argc, char **argv_orig, char **envp) { case 'd': /* skip deterministic */ afl->skip_deterministic = 1; - afl->use_splicing = 1; break; case 'B': /* load bitmap */ -- cgit v1.2.3 From 5540a055c5d71d0b348a5ba33b9239ec2a8802dc Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 10 Oct 2020 11:19:45 +0200 Subject: afl-showmap: free malloced coverage map --- src/afl-showmap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index f4a7c336..545bfaa9 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1160,6 +1160,7 @@ int main(int argc, char **argv_orig, char **envp) { afl_fsrv_deinit(fsrv); if (stdin_file) { ck_free(stdin_file); } + if (collect_coverage) { free(coverage_map); } argv_cpy_free(argv); if (fsrv->qemu_mode) { free(use_argv[2]); } -- cgit v1.2.3 From 01ec0cce4759526499becab169c07b2ccf1eee89 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 10 Oct 2020 15:44:47 +0200 Subject: fix for afl-analyze thanks to JJY-sec! --- src/afl-analyze.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 7c1c269a..bfdd66e9 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -922,11 +922,12 @@ static void usage(u8 *argv0) { /* Main entry point */ -int main(int argc, char **argv, char **envp) { +int main(int argc, char **argv_orig, char **envp) { s32 opt; u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0; char **use_argv; + char **argv = argv_cpy_dup(argc, argv_orig); doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH; -- cgit v1.2.3 From 6a397d6111a21ebbf736237609c1c69d47c40f03 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 11 Oct 2020 14:31:31 +0200 Subject: add new seed selection algo and make it the default --- src/afl-fuzz-init.c | 8 ++++ src/afl-fuzz-one.c | 10 ++++- src/afl-fuzz-queue.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/afl-fuzz.c | 100 +++++++++++++++++++++++++++++------------ 4 files changed, 211 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 65478a78..881bf10f 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -959,6 +959,8 @@ void perform_dry_run(afl_state_t *afl) { /* Remove from fuzzing queue but keep for splicing */ struct queue_entry *p = afl->queue; + p->disabled = 1; + p->perf_score = 0; while (p && p->next != q) p = p->next; @@ -968,6 +970,7 @@ void perform_dry_run(afl_state_t *afl) { afl->queue = q->next; --afl->pending_not_fuzzed; + --afl->active_paths; afl->max_depth = 0; p = afl->queue; @@ -1054,6 +1057,7 @@ restart_outer_cull_loop: duplicates = 1; --afl->pending_not_fuzzed; + afl->active_paths--; // We do not remove any of the memory allocated because for // splicing the data might still be interesting. @@ -1063,11 +1067,15 @@ restart_outer_cull_loop: // we keep the shorter file if (p->len >= q->len) { + p->disabled = 1; + p->perf_score = 0; q->next = p->next; goto restart_inner_cull_loop; } else { + q->disabled = 1; + q->perf_score = 0; if (prev) prev->next = q = p; else diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index c04b492b..6ef728e0 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -554,7 +554,10 @@ u8 fuzz_one_original(afl_state_t *afl) { * PERFORMANCE SCORE * *********************/ - orig_perf = perf_score = calculate_score(afl, afl->queue_cur); + if (likely(!afl->old_seed_selection)) + orig_perf = perf_score = afl->queue_cur->perf_score; + else + orig_perf = perf_score = calculate_score(afl, afl->queue_cur); if (unlikely(perf_score == 0)) { goto abandon_entry; } @@ -2769,7 +2772,10 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { * PERFORMANCE SCORE * *********************/ - orig_perf = perf_score = calculate_score(afl, afl->queue_cur); + if (likely(!afl->old_seed_selection)) + orig_perf = perf_score = afl->queue_cur->perf_score; + else + orig_perf = perf_score = calculate_score(afl, afl->queue_cur); if (unlikely(afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized)) { diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 0d7d0314..d608e890 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -27,6 +27,129 @@ #include #include +inline u32 select_next_queue_entry(afl_state_t *afl) { + + u32 r = rand_below(afl, 0xffffffff); + u32 s = r % afl->queued_paths; + // fprintf(stderr, "select: r=%u s=%u ... r < prob[s]=%f ? s=%u : + // alias[%u]=%u\n", r, s, afl->alias_probability[s], s, s, + // afl->alias_table[s]); + return (r < afl->alias_probability[s] ? s : afl->alias_table[s]); + +} + +void create_alias_table(afl_state_t *afl) { + + u32 n = afl->queued_paths, i = 0, a, g; + + afl->alias_table = + (u32 *)afl_realloc((void **)&afl->alias_table, n * sizeof(u32)); + afl->alias_probability = (double *)afl_realloc( + (void **)&afl->alias_probability, n * sizeof(double)); + double *P = (double *)afl_realloc(AFL_BUF_PARAM(out), n * sizeof(double)); + int * S = (u32 *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32)); + int * L = (u32 *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32)); + + if (!P || !S || !L) FATAL("could not aquire memory for alias table"); + memset((void *)afl->alias_table, 0, n * sizeof(u32)); + memset((void *)afl->alias_probability, 0, n * sizeof(double)); + + double sum = 0; + + for (i = 0; i < n; i++) { + + struct queue_entry *q = afl->queue_buf[i]; + + if (!q->disabled) q->perf_score = calculate_score(afl, q); + + sum += q->perf_score; + /* + if (afl->debug) + fprintf(stderr, "entry %u: score=%f %s (sum: %f)\n", i, q->perf_score, + q->disabled ? "disabled" : "", sum); + */ + + } + + for (i = 0; i < n; i++) { + + struct queue_entry *q = afl->queue_buf[i]; + + P[i] = q->perf_score * n / sum; + + } + + int nS = 0, nL = 0, s; + for (s = (s32)n - 1; s >= 0; --s) { + + if (P[s] < 1) + S[nS++] = s; + else + L[nL++] = s; + + } + + while (nS && nL) { + + a = S[--nS]; + g = L[--nL]; + afl->alias_probability[a] = P[a]; + afl->alias_table[a] = g; + P[g] = P[g] + P[a] - 1; + if (P[g] < 1) + S[nS++] = g; + else + L[nL++] = g; + + } + + while (nL) + afl->alias_probability[L[--nL]] = 1; + + while (nS) + afl->alias_probability[S[--nS]] = 1; + + /* + if (afl->debug) { + + fprintf(stderr, " %-3s %-3s %-9s\n", "entry", "alias", "prob"); + for (u32 i = 0; i < n; ++i) + fprintf(stderr, " %3i %3i %9.7f\n", i, afl->alias_table[i], + afl->alias_probability[i]); + + } + + int prob = 0; + fprintf(stderr, "Alias:"); + for (i = 0; i < n; i++) { + + fprintf(stderr, " [%u]=%u", i, afl->alias_table[i]); + if (afl->alias_table[i] >= n) + prob = i; + + } + + fprintf(stderr, "\n"); + + if (prob) { + + fprintf(stderr, "PROBLEM! alias[%u] = %u\n", prob, + afl->alias_table[prob]); + + for (i = 0; i < n; i++) { + + struct queue_entry *q = afl->queue_buf[i]; + + fprintf(stderr, "%u: score=%f\n", i, q->perf_score); + + } + + } + + */ + +} + /* Mark deterministic checks as done for a particular queue entry. We use the .state file to avoid repeating deterministic fuzzing when resuming aborted scans. */ @@ -237,6 +360,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { if (likely(q->len > 4)) afl->ready_for_splicing_count++; ++afl->queued_paths; + ++afl->active_paths; ++afl->pending_not_fuzzed; afl->cycles_wo_finds = 0; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 24df2997..004adffe 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -115,6 +115,8 @@ static void usage(u8 *argv0, int more_help) { " if using QEMU, just use -c 0.\n\n" "Fuzzing behavior settings:\n" + " -Z - sequential queue selection instead of weighted " + "random\n" " -N - do not unlink the fuzzing input file (for devices " "etc.)\n" " -n - fuzz without instrumentation (non-instrumented mode)\n" @@ -131,8 +133,7 @@ static void usage(u8 *argv0, int more_help) { "Other stuff:\n" " -M/-S id - distributed mode (see docs/parallel_fuzzing.md)\n" - " use -D to force -S secondary to perform deterministic " - "fuzzing\n" + " -M auto-sets -D and -Z (use -d to disable -D)\n" " -F path - sync to a foreign fuzzer queue directory (requires " "-M, can\n" " be specified up to %u times)\n" @@ -250,7 +251,7 @@ int main(int argc, char **argv_orig, char **envp) { s32 opt, i; u64 prev_queued = 0; - u32 sync_interval_cnt = 0, seek_to, show_help = 0, map_size = MAP_SIZE; + u32 sync_interval_cnt = 0, seek_to = 0, show_help = 0, map_size = MAP_SIZE; u8 *extras_dir[4]; u8 mem_limit_given = 0, exit_1 = 0, debug = 0, extras_dir_cnt = 0 /*, have_p = 0*/; @@ -287,10 +288,14 @@ int main(int argc, char **argv_orig, char **envp) { while ((opt = getopt( argc, argv, - "+b:c:i:I:o:f:F:m:t:T:dDnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:")) > 0) { + "+b:c:i:I:o:f:F:m:t:T:dDnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:Z")) > 0) { switch (opt) { + case 'Z': + afl->old_seed_selection = 1; + break; + case 'I': afl->infoexec = optarg; break; @@ -355,14 +360,16 @@ int main(int argc, char **argv_orig, char **envp) { afl->schedule = RARE; - } else if (!stricmp(optarg, "explore") || !stricmp(optarg, "afl")) { - - afl->schedule = EXPLORE; + } else if (!stricmp(optarg, "explore") || !stricmp(optarg, "afl") || - } else if (!stricmp(optarg, "seek") || !stricmp(optarg, "default") || + !stricmp(optarg, "default") || !stricmp(optarg, "normal")) { + afl->schedule = EXPLORE; + + } else if (!stricmp(optarg, "seek")) { + afl->schedule = SEEK; } else { @@ -404,7 +411,8 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); } afl->sync_id = ck_strdup(optarg); - afl->skip_deterministic = 0; + afl->skip_deterministic = 0; // force determinsitic fuzzing + afl->old_seed_selection = 1; // force old queue walking seed selection if ((c = strchr(afl->sync_id, ':'))) { @@ -1131,8 +1139,10 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->is_secondary_node && check_main_node_exists(afl) == 0) { - WARNF("no -M main node found. You need to run one main instance!"); - sleep(3); + WARNF( + "no -M main node found. It is recommended to run exactly one main " + "instance."); + sleep(1); } @@ -1302,7 +1312,7 @@ int main(int argc, char **argv_orig, char **envp) { show_init_stats(afl); - seek_to = find_start_position(afl); + if (unlikely(afl->old_seed_selection)) seek_to = find_start_position(afl); write_stats_file(afl, 0, 0, 0); maybe_update_plot_file(afl, 0, 0); @@ -1324,28 +1334,37 @@ int main(int argc, char **argv_orig, char **envp) { // real start time, we reset, so this works correctly with -V afl->start_time = get_cur_time(); + u32 runs_in_current_cycle = (u32)-1; + u32 prev_queued_paths = 0; + while (1) { u8 skipped_fuzz; cull_queue(afl); - if (!afl->queue_cur) { + if (unlikely((!afl->old_seed_selection && + runs_in_current_cycle > afl->queued_paths) || + (afl->old_seed_selection && !afl->queue_cur))) { ++afl->queue_cycle; - afl->current_entry = 0; + runs_in_current_cycle = 0; afl->cur_skipped_paths = 0; - afl->queue_cur = afl->queue; - if (seek_to) { + if (unlikely(afl->old_seed_selection)) { - afl->current_entry = seek_to; - afl->queue_cur = afl->queue_buf[seek_to]; - seek_to = 0; + afl->current_entry = 0; + afl->queue_cur = afl->queue; - } + if (unlikely(seek_to)) { - // show_stats(afl); + afl->current_entry = seek_to; + afl->queue_cur = afl->queue_buf[seek_to]; + seek_to = 0; + + } + + } if (unlikely(afl->not_on_tty)) { @@ -1366,9 +1385,11 @@ int main(int argc, char **argv_orig, char **envp) { switch (afl->expand_havoc) { case 0: + // this adds extra splicing mutation options to havoc mode afl->expand_havoc = 1; break; case 1: + // add MOpt mutator if (afl->limit_time_sig == 0 && !afl->custom_only && !afl->python_only) { @@ -1381,25 +1402,26 @@ int main(int argc, char **argv_orig, char **envp) { break; case 2: // if (!have_p) afl->schedule = EXPLOIT; + // increase havoc mutations per fuzz attempt afl->havoc_stack_pow2++; afl->expand_havoc = 3; break; case 3: + // further increase havoc mutations per fuzz attempt afl->havoc_stack_pow2++; afl->expand_havoc = 4; break; case 4: + // if not in sync mode, enable deterministic mode? + // if (!afl->sync_dir) afl->skip_deterministic = 0; + afl->expand_havoc = 5; + break; + case 5: // nothing else currently break; } - if (afl->expand_havoc) { - - } else - - afl->expand_havoc = 1; - } else { afl->use_splicing = 1; @@ -1470,6 +1492,22 @@ int main(int argc, char **argv_orig, char **envp) { } + if (likely(!afl->old_seed_selection)) { + + ++runs_in_current_cycle; + if (unlikely(prev_queued_paths < afl->queued_paths)) { + + // we have new queue entries since the last run, recreate alias table + prev_queued_paths = afl->queued_paths; + create_alias_table(afl); + + } + + afl->current_entry = select_next_queue_entry(afl); + afl->queue_cur = afl->queue_buf[afl->current_entry]; + + } + skipped_fuzz = fuzz_one(afl); if (!skipped_fuzz && !afl->stop_soon && afl->sync_id) { @@ -1490,8 +1528,12 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->stop_soon) { break; } - afl->queue_cur = afl->queue_cur->next; - ++afl->current_entry; + if (unlikely(afl->old_seed_selection)) { + + afl->queue_cur = afl->queue_cur->next; + ++afl->current_entry; + + } } -- cgit v1.2.3 From dab017dddaaab6d836a590f7bba3eea3549758d2 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 12 Oct 2020 02:26:14 +0200 Subject: no -M/-S: auto-set -S default --- src/afl-fuzz.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 004adffe..d42a0d36 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -411,8 +411,8 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); } afl->sync_id = ck_strdup(optarg); - afl->skip_deterministic = 0; // force determinsitic fuzzing - afl->old_seed_selection = 1; // force old queue walking seed selection + afl->skip_deterministic = 0; // force determinsitic fuzzing + afl->old_seed_selection = 1; // force old queue walking seed selection if ((c = strchr(afl->sync_id, ':'))) { @@ -847,6 +847,8 @@ int main(int argc, char **argv_orig, char **envp) { "Eißfeldt, Andrea Fioraldi and Dominik Maier"); OKF("afl++ is open source, get it at " "https://github.com/AFLplusplus/AFLplusplus"); + OKF("NOTE: This is v3.x which changes several defaults and behaviours - see " + "README.md"); if (afl->sync_id && afl->is_main_node && afl->afl_env.afl_custom_mutator_only) { @@ -1135,15 +1137,19 @@ int main(int argc, char **argv_orig, char **envp) { WARNF("it is wasteful to run more than one main node!"); sleep(1); - } - - if (afl->is_secondary_node && check_main_node_exists(afl) == 0) { + } else if (afl->is_secondary_node && check_main_node_exists(afl) == 0) { WARNF( "no -M main node found. It is recommended to run exactly one main " "instance."); sleep(1); + } else if (!afl->sync_id) { + + afl->sync_id = "default"; + afl->is_secondary_node = 1; + OKF("no -M/-S set, autoconfiguring for \"-S %s\"", afl->sync_id); + } #ifdef RAND_TEST_VALUES -- cgit v1.2.3 From b7e0490bcdaa7fa792a9dccfa5983e03af92730e Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 12 Oct 2020 03:44:34 +0200 Subject: Revert "Merge branch 'memcache_marc' into dev" This reverts commit c03fbcedaa68db5324423975a34331287426f7c2, reversing changes made to dab017dddaaab6d836a590f7bba3eea3549758d2. --- src/afl-fuzz-one.c | 157 +++++++++++++++++++++++++++++++-------------------- src/afl-fuzz-queue.c | 87 ---------------------------- src/afl-fuzz.c | 5 +- 3 files changed, 97 insertions(+), 152 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index ebe541a2..6ef728e0 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -370,7 +370,7 @@ static void locate_diffs(u8 *ptr1, u8 *ptr2, u32 len, s32 *first, s32 *last) { u8 fuzz_one_original(afl_state_t *afl) { - s32 len, temp_len; + s32 len, fd, temp_len; u32 j; u32 i; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; @@ -453,9 +453,28 @@ u8 fuzz_one_original(afl_state_t *afl) { } - orig_in = in_buf = queue_testcase_take(afl, afl->queue_cur); + /* Map the test case into memory. */ + + fd = open(afl->queue_cur->fname, O_RDONLY); + + if (unlikely(fd < 0)) { + + PFATAL("Unable to open '%s'", afl->queue_cur->fname); + + } + len = afl->queue_cur->len; + orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + + if (unlikely(orig_in == MAP_FAILED)) { + + PFATAL("Unable to mmap '%s' with len %d", afl->queue_cur->fname, len); + + } + + close(fd); + /* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every single byte anyway, so it wouldn't give us any performance or memory usage benefits. */ @@ -1678,7 +1697,7 @@ custom_mutator_stage: for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { - struct queue_entry *target = NULL; + struct queue_entry *target; u32 tid; u8 * new_buf = NULL; u32 target_len = 0; @@ -1701,7 +1720,17 @@ custom_mutator_stage: afl->splicing_with = tid; /* Read the additional testcase into a new buffer. */ - new_buf = queue_testcase_take(afl, target); + fd = open(target->fname, O_RDONLY); + if (unlikely(fd < 0)) { + + PFATAL("Unable to open '%s'", target->fname); + + } + + new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), target->len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } + ck_read(fd, new_buf, target->len, target->fname); + close(fd); target_len = target->len; } @@ -1712,13 +1741,6 @@ custom_mutator_stage: el->afl_custom_fuzz(el->data, out_buf, len, &mutated_buf, new_buf, target_len, max_seed_size); - if (new_buf) { - - queue_testcase_release(afl, target); - new_buf = NULL; - - } - if (unlikely(!mutated_buf)) { FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size); @@ -2301,53 +2323,52 @@ havoc_stage: /* Overwrite bytes with a randomly selected chunk from another testcase or insert that chunk. */ - if (afl->queued_paths < 4) { break; } + if (afl->queued_paths < 4) break; /* Pick a random queue entry and seek to it. */ u32 tid; - do { - + do tid = rand_below(afl, afl->queued_paths); - - } while (tid == afl->current_entry); + while (tid == afl->current_entry); struct queue_entry *target = afl->queue_buf[tid]; /* Make sure that the target has a reasonable length. */ - while (target && (target->len < 2 || target == afl->queue_cur)) { - + while (target && (target->len < 2 || target == afl->queue_cur)) target = target->next; - } + if (!target) break; - if (!target) { break; } + /* Read the testcase into a new buffer. */ - u32 new_len = target->len; + fd = open(target->fname, O_RDONLY); - /* Get the testcase contents for splicing. */ - u8 *new_buf = queue_testcase_take(afl, target); + if (unlikely(fd < 0)) { - u8 overwrite = 0; - if (temp_len >= 2 && rand_below(afl, 2)) { + PFATAL("Unable to open '%s'", target->fname); - overwrite = 1; + } - } else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { + u32 new_len = target->len; + u8 *new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), new_len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } - if (temp_len >= 2) { + ck_read(fd, new_buf, new_len, target->fname); - overwrite = 1; + close(fd); - } else { + u8 overwrite = 0; + if (temp_len >= 2 && rand_below(afl, 2)) + overwrite = 1; + else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { - queue_testcase_release(afl, target); - new_buf = NULL; + if (temp_len >= 2) + overwrite = 1; + else break; - } - } if (overwrite) { @@ -2393,9 +2414,6 @@ havoc_stage: } - /* We don't need this splice testcase anymore */ - queue_testcase_release(afl, target); - new_buf = NULL; break; } @@ -2501,17 +2519,24 @@ retry_splicing: if (!target) { goto retry_splicing; } - /* Get the testcase buffer */ - u8 *splice_buf = queue_testcase_take(afl, target); + /* Read the testcase into a new buffer. */ + + fd = open(target->fname, O_RDONLY); + + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); } + new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); if (unlikely(!new_buf)) { PFATAL("alloc"); } + ck_read(fd, new_buf, target->len, target->fname); + + close(fd); + /* Find a suitable splicing location, somewhere between the first and the last differing byte. Bail out if the difference is just a single byte or so. */ - locate_diffs(in_buf, splice_buf, MIN(len, (s64)target->len), &f_diff, - &l_diff); + locate_diffs(in_buf, new_buf, MIN(len, (s64)target->len), &f_diff, &l_diff); if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { goto retry_splicing; } @@ -2523,7 +2548,6 @@ retry_splicing: len = target->len; memcpy(new_buf, in_buf, split_at); - memcpy(new_buf + split_at, splice_buf + split_at, target->len - split_at); afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); in_buf = new_buf; @@ -2531,9 +2555,6 @@ retry_splicing: if (unlikely(!out_buf)) { PFATAL("alloc"); } memcpy(out_buf, in_buf, len); - queue_testcase_release(afl, target); - splice_buf = NULL; - goto custom_mutator_stage; /* ???: While integrating Python module, the author decided to jump to python stage, but the reason behind this is not clear.*/ @@ -2564,8 +2585,7 @@ abandon_entry: ++afl->queue_cur->fuzz_level; - queue_testcase_release(afl, afl->queue_cur); - orig_in = NULL; + munmap(orig_in, afl->queue_cur->len); return ret_val; @@ -2587,7 +2607,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { } - s32 len, temp_len; + s32 len, fd, temp_len; u32 i; u32 j; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; @@ -2652,9 +2672,23 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { } /* Map the test case into memory. */ - orig_in = in_buf = queue_testcase_take(afl, afl->queue_cur); + + fd = open(afl->queue_cur->fname, O_RDONLY); + + if (fd < 0) { PFATAL("Unable to open '%s'", afl->queue_cur->fname); } + len = afl->queue_cur->len; + orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + + if (orig_in == MAP_FAILED) { + + PFATAL("Unable to mmap '%s'", afl->queue_cur->fname); + + } + + close(fd); + /* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every single byte anyway, so it wouldn't give us any performance or memory usage benefits. */ @@ -4494,24 +4528,31 @@ pacemaker_fuzzing: if (!target) { goto retry_splicing_puppet; } /* Read the testcase into a new buffer. */ - u8 *splicing_buf = queue_testcase_take(afl, target); + + fd = open(target->fname, O_RDONLY); + + if (fd < 0) { PFATAL("Unable to open '%s'", target->fname); } + + new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } + + ck_read(fd, new_buf, target->len, target->fname); + + close(fd); /* Find a suitable splicin g location, somewhere between the first and the last differing byte. Bail out if the difference is just a single byte or so. */ - locate_diffs(in_buf, splicing_buf, MIN(len, (s32)target->len), &f_diff, + locate_diffs(in_buf, new_buf, MIN(len, (s32)target->len), &f_diff, &l_diff); if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { - queue_testcase_release(afl, target); goto retry_splicing_puppet; } - new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); - /* Split somewhere between the first and last differing byte. */ split_at = f_diff + rand_below(afl, l_diff - f_diff); @@ -4520,17 +4561,12 @@ pacemaker_fuzzing: len = target->len; memcpy(new_buf, in_buf, split_at); - memcpy(new_buf + split_at, splicing_buf + split_at, - target->len - split_at); afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); in_buf = new_buf; out_buf = afl_realloc(AFL_BUF_PARAM(out), len); if (unlikely(!out_buf)) { PFATAL("alloc"); } memcpy(out_buf, in_buf, len); - queue_testcase_release(afl, target); - splicing_buf = NULL; - goto havoc_stage_puppet; } /* if splice_cycle */ @@ -4564,8 +4600,7 @@ pacemaker_fuzzing: // if (afl->queue_cur->favored) --afl->pending_favored; // } - queue_testcase_release(afl, afl->queue_cur); - orig_in = NULL; + munmap(orig_in, afl->queue_cur->len); if (afl->key_puppet == 1) { diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index a034b168..d608e890 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -343,7 +343,6 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { q->depth = afl->cur_depth + 1; q->passed_det = passed_det; q->trace_mini = NULL; - q->testcase_buf = NULL; if (q->depth > afl->max_depth) { afl->max_depth = q->depth; } @@ -892,89 +891,3 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { } -/* Tell afl that this testcase may be evicted from the cache */ -inline void queue_testcase_release(afl_state_t *afl, struct queue_entry *q) { - - (void)afl; - if (unlikely(q->testcase_refs == 0)) { - - FATAL("Testcase refcount reduced past 0"); - - } - - q->testcase_refs--; - -} - -/* Returns the testcase buf from the file behind this queue entry. - Increases the refcount. */ -u8 *queue_testcase_take(afl_state_t *afl, struct queue_entry *q) { - - if (!q->testcase_buf) { - - u32 tid = 0; - /* Buf not cached, let's do that now */ - - if (likely(afl->q_testcase_cache_count == TESTCASE_CACHE_SIZE)) { - - /* Cache full. We neet to evict one to map one. - Get a random one which is not in use */ - do { - - tid = rand_below(afl, afl->q_testcase_cache_count); - - } while (afl->q_testcase_cache[tid]->testcase_refs > 0); - - struct queue_entry *old_cached = afl->q_testcase_cache[tid]; - /* free the current buf from cache */ - munmap(old_cached->testcase_buf, old_cached->len); - old_cached->testcase_buf = NULL; - - } else { - - tid = afl->q_testcase_cache_count; - afl->q_testcase_cache_count++; - - } - - /* Map the test case into memory. */ - - int fd = open(q->fname, O_RDONLY); - - if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); } - - u32 len = q->len; - - q->testcase_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - - if (unlikely(q->testcase_buf == MAP_FAILED)) { - - PFATAL("Unable to mmap '%s' with len %d", q->fname, len); - - } - - close(fd); - - /* Register us as cached */ - afl->q_testcase_cache[tid] = q; - - } - - q->testcase_refs++; - if (unlikely(!q->testcase_buf || !q->testcase_refs)) { - if (!q->testcase_buf) { - - FATAL("Testcase buf is NULL, this should never happen"); - - } - if (!q->testcase_refs) { - - FATAL("Testcase ref overflow. Missing a testcase release somwhere?"); - - } - } - - return q->testcase_buf; - -} - diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index cb5eb37a..d42a0d36 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1174,12 +1174,9 @@ int main(int argc, char **argv_orig, char **envp) { if (extras_dir_cnt) { - for (i = 0; i < extras_dir_cnt; i++) { - + for (i = 0; i < extras_dir_cnt; i++) load_extras(afl, extras_dir[i]); - } - dedup_extras(afl); OKF("Loaded a total of %u extras.", afl->extras_cnt); -- cgit v1.2.3 From d6da5605c80d65091375c08ae5389d14d671500a Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 12 Oct 2020 04:03:42 +0200 Subject: fix splicing selection --- src/afl-fuzz-one.c | 47 ++++++++--------------------------------------- 1 file changed, 8 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 6ef728e0..fc092f8d 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1712,9 +1712,9 @@ custom_mutator_stage: tid = rand_below(afl, afl->queued_paths); - } while (unlikely(tid == afl->current_entry && + } while (unlikely(tid == afl->current_entry || - afl->queue_buf[tid]->len >= 4)); + afl->queue_buf[tid]->len < 4)); target = afl->queue_buf[tid]; afl->splicing_with = tid; @@ -1872,7 +1872,7 @@ havoc_stage: u32 r_max, r; - if (unlikely(afl->expand_havoc)) { + if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) { /* add expensive havoc cases here, they are activated after a full cycle without finds happened */ @@ -2323,24 +2323,15 @@ havoc_stage: /* Overwrite bytes with a randomly selected chunk from another testcase or insert that chunk. */ - if (afl->queued_paths < 4) break; - /* Pick a random queue entry and seek to it. */ u32 tid; do tid = rand_below(afl, afl->queued_paths); - while (tid == afl->current_entry); + while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4); struct queue_entry *target = afl->queue_buf[tid]; - /* Make sure that the target has a reasonable length. */ - - while (target && (target->len < 2 || target == afl->queue_cur)) - target = target->next; - - if (!target) break; - /* Read the testcase into a new buffer. */ fd = open(target->fname, O_RDONLY); @@ -2480,7 +2471,7 @@ havoc_stage: retry_splicing: if (afl->use_splicing && splice_cycle++ < SPLICE_CYCLES && - afl->queued_paths > 1 && afl->queue_cur->len > 1) { + afl->ready_for_splicing_count > 1 && afl->queue_cur->len >= 4) { struct queue_entry *target; u32 tid, split_at; @@ -2503,22 +2494,11 @@ retry_splicing: tid = rand_below(afl, afl->queued_paths); - } while (tid == afl->current_entry); + } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4); afl->splicing_with = tid; target = afl->queue_buf[tid]; - /* Make sure that the target has a reasonable length. */ - - while (target && (target->len < 2 || target == afl->queue_cur)) { - - target = target->next; - ++afl->splicing_with; - - } - - if (!target) { goto retry_splicing; } - /* Read the testcase into a new buffer. */ fd = open(target->fname, O_RDONLY); @@ -4487,7 +4467,7 @@ pacemaker_fuzzing: if (afl->use_splicing && splice_cycle++ < (u32)afl->SPLICE_CYCLES_puppet && - afl->queued_paths > 1 && afl->queue_cur->len > 1) { + afl->ready_for_splicing_count > 1 && afl->queue_cur->len >= 4) { struct queue_entry *target; u32 tid, split_at; @@ -4511,22 +4491,11 @@ pacemaker_fuzzing: tid = rand_below(afl, afl->queued_paths); - } while (tid == afl->current_entry); + } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4); afl->splicing_with = tid; target = afl->queue_buf[tid]; - /* Make sure that the target has a reasonable length. */ - - while (target && (target->len < 2 || target == afl->queue_cur)) { - - target = target->next; - ++afl->splicing_with; - - } - - if (!target) { goto retry_splicing_puppet; } - /* Read the testcase into a new buffer. */ fd = open(target->fname, O_RDONLY); -- cgit v1.2.3 From aef0cd5877e0e4d3450610d48c4f6188a114d2b3 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 12 Oct 2020 04:41:04 +0200 Subject: fix sync mode --- src/afl-fuzz.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index d42a0d36..e58d3d34 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -249,7 +249,7 @@ static int stricmp(char const *a, char const *b) { int main(int argc, char **argv_orig, char **envp) { - s32 opt, i; + s32 opt, i, auto_sync = 0; u64 prev_queued = 0; u32 sync_interval_cnt = 0, seek_to = 0, show_help = 0, map_size = MAP_SIZE; u8 *extras_dir[4]; @@ -847,7 +847,7 @@ int main(int argc, char **argv_orig, char **envp) { "Eißfeldt, Andrea Fioraldi and Dominik Maier"); OKF("afl++ is open source, get it at " "https://github.com/AFLplusplus/AFLplusplus"); - OKF("NOTE: This is v3.x which changes several defaults and behaviours - see " + OKF("NOTE: This is v3.x which changes defaults and behaviours - see " "README.md"); if (afl->sync_id && afl->is_main_node && @@ -880,6 +880,15 @@ int main(int argc, char **argv_orig, char **envp) { afl->power_name = power_names[afl->schedule]; + if (!afl->sync_id) { + + auto_sync = 1; + afl->sync_id = ck_strdup("default"); + afl->is_secondary_node = 1; + OKF("no -M/-S set, autoconfiguring for \"-S %s\"", afl->sync_id); + + } + if (afl->sync_id) { fix_up_sync(afl); } if (!strcmp(afl->in_dir, afl->out_dir)) { @@ -1137,19 +1146,15 @@ int main(int argc, char **argv_orig, char **envp) { WARNF("it is wasteful to run more than one main node!"); sleep(1); - } else if (afl->is_secondary_node && check_main_node_exists(afl) == 0) { + } else if (!auto_sync && afl->is_secondary_node && + + check_main_node_exists(afl) == 0) { WARNF( "no -M main node found. It is recommended to run exactly one main " "instance."); sleep(1); - } else if (!afl->sync_id) { - - afl->sync_id = "default"; - afl->is_secondary_node = 1; - OKF("no -M/-S set, autoconfiguring for \"-S %s\"", afl->sync_id); - } #ifdef RAND_TEST_VALUES @@ -1419,7 +1424,7 @@ int main(int argc, char **argv_orig, char **envp) { break; case 4: // if not in sync mode, enable deterministic mode? - // if (!afl->sync_dir) afl->skip_deterministic = 0; + // if (!afl->sync_id) afl->skip_deterministic = 0; afl->expand_havoc = 5; break; case 5: -- cgit v1.2.3 From 15099f7f5a129dd3679df646ed2b50a3196188f1 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 12 Oct 2020 04:48:02 +0200 Subject: fix afl-cc.8 generation --- src/afl-fuzz.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e58d3d34..6498eb30 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1179,9 +1179,12 @@ int main(int argc, char **argv_orig, char **envp) { if (extras_dir_cnt) { - for (i = 0; i < extras_dir_cnt; i++) + for (i = 0; i < extras_dir_cnt; i++) { + load_extras(afl, extras_dir[i]); + } + dedup_extras(afl); OKF("Loaded a total of %u extras.", afl->extras_cnt); -- cgit v1.2.3 From d9b63766dfdb8feeb1dc6f7c51c17abf07ee4086 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 12 Oct 2020 11:12:16 +0200 Subject: fix new seed selection algo --- src/afl-fuzz-queue.c | 59 ++++++++++++--------------------------------------- src/afl-performance.c | 10 ++++++++- 2 files changed, 23 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index d608e890..f224d851 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -27,17 +27,22 @@ #include #include +/* select next queue entry based on alias algo - fast! */ + inline u32 select_next_queue_entry(afl_state_t *afl) { - u32 r = rand_below(afl, 0xffffffff); - u32 s = r % afl->queued_paths; - // fprintf(stderr, "select: r=%u s=%u ... r < prob[s]=%f ? s=%u : - // alias[%u]=%u\n", r, s, afl->alias_probability[s], s, s, - // afl->alias_table[s]); - return (r < afl->alias_probability[s] ? s : afl->alias_table[s]); + u32 s = rand_below(afl, afl->queued_paths); + double p = rand_next_percent(afl); + /* + fprintf(stderr, "select: p=%f s=%u ... p < prob[s]=%f ? s=%u : alias[%u]=%u" + " ==> %u\n", p, s, afl->alias_probability[s], s, s, afl->alias_table[s], p < afl->alias_probability[s] ? s : afl->alias_table[s]); + */ + return (p < afl->alias_probability[s] ? s : afl->alias_table[s]); } +/* create the alias table that allows weighted random selection - expensive */ + void create_alias_table(afl_state_t *afl) { u32 n = afl->queued_paths, i = 0, a, g; @@ -63,11 +68,6 @@ void create_alias_table(afl_state_t *afl) { if (!q->disabled) q->perf_score = calculate_score(afl, q); sum += q->perf_score; - /* - if (afl->debug) - fprintf(stderr, "entry %u: score=%f %s (sum: %f)\n", i, q->perf_score, - q->disabled ? "disabled" : "", sum); - */ } @@ -110,41 +110,10 @@ void create_alias_table(afl_state_t *afl) { afl->alias_probability[S[--nS]] = 1; /* - if (afl->debug) { - - fprintf(stderr, " %-3s %-3s %-9s\n", "entry", "alias", "prob"); + fprintf(stderr, " %-3s %-3s %-9s %-9s\n", "entry", "alias", "prob", "perf"); for (u32 i = 0; i < n; ++i) - fprintf(stderr, " %3i %3i %9.7f\n", i, afl->alias_table[i], - afl->alias_probability[i]); - - } - - int prob = 0; - fprintf(stderr, "Alias:"); - for (i = 0; i < n; i++) { - - fprintf(stderr, " [%u]=%u", i, afl->alias_table[i]); - if (afl->alias_table[i] >= n) - prob = i; - - } - - fprintf(stderr, "\n"); - - if (prob) { - - fprintf(stderr, "PROBLEM! alias[%u] = %u\n", prob, - afl->alias_table[prob]); - - for (i = 0; i < n; i++) { - - struct queue_entry *q = afl->queue_buf[i]; - - fprintf(stderr, "%u: score=%f\n", i, q->perf_score); - - } - - } + fprintf(stderr, " %3i %3i %9.7f %9.7f\n", i, afl->alias_table[i], + afl->alias_probability[i], afl->queue_buf[i]->perf_score); */ diff --git a/src/afl-performance.c b/src/afl-performance.c index 7a80ac4b..6fa95dea 100644 --- a/src/afl-performance.c +++ b/src/afl-performance.c @@ -47,7 +47,7 @@ void rand_set_seed(afl_state_t *afl, s64 init_seed) { } -uint64_t rand_next(afl_state_t *afl) { +inline uint64_t rand_next(afl_state_t *afl) { const uint64_t result = rotl(afl->rand_seed[0] + afl->rand_seed[3], 23) + afl->rand_seed[0]; @@ -67,6 +67,14 @@ uint64_t rand_next(afl_state_t *afl) { } +/* returns a double between 0.000000000 and 1.000000000 */ + +inline double rand_next_percent(afl_state_t *afl) { + + return (double)(((double)rand_next(afl)) / (double) 0xffffffffffffffff); + +} + /* This is the jump function for the generator. It is equivalent to 2^128 calls to rand_next(); it can be used to generate 2^128 non-overlapping subsequences for parallel computations. */ -- cgit v1.2.3 From 56ac3fcdc511d124ad058412021ead21bbbcf4bf Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 14 Oct 2020 15:30:30 +0200 Subject: configurable testcache with malloc (#581) * cache item number to cache memory size * reload testcase if trimming changed the size * fix splicing selection * slim splicing * import sync fix * write testcache stats to fuzzer_stats * fix new seed selection algo * malloc+read instead of mmap * fix * testcache is configurable now and no reference counts * fixes compilation, test script * fixes * switch TEST_CC to afl-cc in makefile * code format * fix * fix crash * fix crash * fix env help output * remove unnecessary pointer resets * fix endless loop bug * actually use the cache if set * one more fix * increase default cache entries, add default cache size value to config.h Co-authored-by: hexcoder- --- src/afl-fuzz-init.c | 4 +- src/afl-fuzz-one.c | 169 +++++++++++--------------------------------------- src/afl-fuzz-queue.c | 167 ++++++++++++++++++++++++++++++++++++++++++++----- src/afl-fuzz-run.c | 6 ++ src/afl-fuzz-state.c | 8 +++ src/afl-fuzz-stats.c | 7 ++- src/afl-fuzz.c | 29 +++++++-- src/afl-performance.c | 2 +- 8 files changed, 234 insertions(+), 158 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 881bf10f..607b652f 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1045,7 +1045,7 @@ restart_outer_cull_loop: while (q) { - if (q->cal_failed || !q->exec_cksum) continue; + if (q->cal_failed || !q->exec_cksum) { goto next_entry; } restart_inner_cull_loop: @@ -1090,6 +1090,8 @@ restart_outer_cull_loop: } + next_entry: + prev = q; q = q->next; diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index fc092f8d..154e4b45 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -370,7 +370,7 @@ static void locate_diffs(u8 *ptr1, u8 *ptr2, u32 len, s32 *first, s32 *last) { u8 fuzz_one_original(afl_state_t *afl) { - s32 len, fd, temp_len; + s32 len, temp_len; u32 j; u32 i; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; @@ -453,32 +453,9 @@ u8 fuzz_one_original(afl_state_t *afl) { } - /* Map the test case into memory. */ - - fd = open(afl->queue_cur->fname, O_RDONLY); - - if (unlikely(fd < 0)) { - - PFATAL("Unable to open '%s'", afl->queue_cur->fname); - - } - + orig_in = in_buf = queue_testcase_get(afl, afl->queue_cur); len = afl->queue_cur->len; - orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - - if (unlikely(orig_in == MAP_FAILED)) { - - PFATAL("Unable to mmap '%s' with len %d", afl->queue_cur->fname, len); - - } - - close(fd); - - /* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every - single byte anyway, so it wouldn't give us any performance or memory usage - benefits. */ - out_buf = afl_realloc(AFL_BUF_PARAM(out), len); if (unlikely(!out_buf)) { PFATAL("alloc"); } @@ -526,6 +503,7 @@ u8 fuzz_one_original(afl_state_t *afl) { !afl->disable_trim)) { u8 res = trim_case(afl, afl->queue_cur, in_buf); + orig_in = in_buf = queue_testcase_get(afl, afl->queue_cur); if (unlikely(res == FSRV_RUN_ERROR)) { @@ -1720,17 +1698,7 @@ custom_mutator_stage: afl->splicing_with = tid; /* Read the additional testcase into a new buffer. */ - fd = open(target->fname, O_RDONLY); - if (unlikely(fd < 0)) { - - PFATAL("Unable to open '%s'", target->fname); - - } - - new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), target->len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - ck_read(fd, new_buf, target->len, target->fname); - close(fd); + new_buf = queue_testcase_get(afl, target); target_len = target->len; } @@ -2182,7 +2150,6 @@ havoc_stage: afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); out_buf = new_buf; - new_buf = NULL; temp_len += clone_len; } @@ -2326,43 +2293,21 @@ havoc_stage: /* Pick a random queue entry and seek to it. */ u32 tid; - do - tid = rand_below(afl, afl->queued_paths); - while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4); - - struct queue_entry *target = afl->queue_buf[tid]; - - /* Read the testcase into a new buffer. */ - - fd = open(target->fname, O_RDONLY); - - if (unlikely(fd < 0)) { - - PFATAL("Unable to open '%s'", target->fname); - - } - - u32 new_len = target->len; - u8 *new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), new_len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - - ck_read(fd, new_buf, new_len, target->fname); + do { - close(fd); + tid = rand_below(afl, afl->queued_paths); - u8 overwrite = 0; - if (temp_len >= 2 && rand_below(afl, 2)) - overwrite = 1; - else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { + } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4); - if (temp_len >= 2) - overwrite = 1; - else - break; + /* Get the testcase for splicing. */ + struct queue_entry *target = afl->queue_buf[tid]; + u32 new_len = target->len; + u8 * new_buf = queue_testcase_get(afl, target); - } + if ((temp_len >= 2 && rand_below(afl, 2)) || + temp_len + HAVOC_BLK_XL >= MAX_FILE) { - if (overwrite) { + /* overwrite mode */ u32 copy_from, copy_to, copy_len; @@ -2376,15 +2321,16 @@ havoc_stage: } else { + /* insert mode */ + u32 clone_from, clone_to, clone_len; clone_len = choose_block_len(afl, new_len); clone_from = rand_below(afl, new_len - clone_len + 1); + clone_to = rand_below(afl, temp_len + 1); - clone_to = rand_below(afl, temp_len); - - u8 *temp_buf = - afl_realloc(AFL_BUF_PARAM(out_scratch), temp_len + clone_len); + u8 *temp_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), + temp_len + clone_len + 1); if (unlikely(!temp_buf)) { PFATAL("alloc"); } /* Head */ @@ -2496,21 +2442,10 @@ retry_splicing: } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4); + /* Get the testcase */ afl->splicing_with = tid; target = afl->queue_buf[tid]; - - /* Read the testcase into a new buffer. */ - - fd = open(target->fname, O_RDONLY); - - if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); } - - new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - - ck_read(fd, new_buf, target->len, target->fname); - - close(fd); + new_buf = queue_testcase_get(afl, target); /* Find a suitable splicing location, somewhere between the first and the last differing byte. Bail out if the difference is just a single @@ -2527,18 +2462,16 @@ retry_splicing: /* Do the thing. */ len = target->len; - memcpy(new_buf, in_buf, split_at); - afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); - in_buf = new_buf; + afl->in_scratch_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), len); + memcpy(afl->in_scratch_buf, in_buf, split_at); + memcpy(afl->in_scratch_buf + split_at, new_buf, len - split_at); + in_buf = afl->in_scratch_buf; out_buf = afl_realloc(AFL_BUF_PARAM(out), len); if (unlikely(!out_buf)) { PFATAL("alloc"); } memcpy(out_buf, in_buf, len); goto custom_mutator_stage; - /* ???: While integrating Python module, the author decided to jump to - python stage, but the reason behind this is not clear.*/ - // goto havoc_stage; } @@ -2564,9 +2497,7 @@ abandon_entry: } ++afl->queue_cur->fuzz_level; - - munmap(orig_in, afl->queue_cur->len); - + orig_in = NULL; return ret_val; #undef FLIP_BIT @@ -2587,7 +2518,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { } - s32 len, fd, temp_len; + s32 len, temp_len; u32 i; u32 j; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; @@ -2652,32 +2583,11 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { } /* Map the test case into memory. */ - - fd = open(afl->queue_cur->fname, O_RDONLY); - - if (fd < 0) { PFATAL("Unable to open '%s'", afl->queue_cur->fname); } - + orig_in = in_buf = queue_testcase_get(afl, afl->queue_cur); len = afl->queue_cur->len; - - orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - - if (orig_in == MAP_FAILED) { - - PFATAL("Unable to mmap '%s'", afl->queue_cur->fname); - - } - - close(fd); - - /* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every - single byte anyway, so it wouldn't give us any performance or memory usage - benefits. */ - out_buf = afl_realloc(AFL_BUF_PARAM(out), len); if (unlikely(!out_buf)) { PFATAL("alloc"); } - afl->subseq_tmouts = 0; - afl->cur_depth = afl->queue_cur->depth; /******************************************* @@ -2721,6 +2631,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { u32 old_len = afl->queue_cur->len; u8 res = trim_case(afl, afl->queue_cur, in_buf); + orig_in = in_buf = queue_testcase_get(afl, afl->queue_cur); if (res == FSRV_RUN_ERROR) { @@ -4497,17 +4408,7 @@ pacemaker_fuzzing: target = afl->queue_buf[tid]; /* Read the testcase into a new buffer. */ - - fd = open(target->fname, O_RDONLY); - - if (fd < 0) { PFATAL("Unable to open '%s'", target->fname); } - - new_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), target->len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - - ck_read(fd, new_buf, target->len, target->fname); - - close(fd); + new_buf = queue_testcase_get(afl, target); /* Find a suitable splicin g location, somewhere between the first and the last differing byte. Bail out if the difference is just a single @@ -4529,9 +4430,11 @@ pacemaker_fuzzing: /* Do the thing. */ len = target->len; - memcpy(new_buf, in_buf, split_at); - afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); - in_buf = new_buf; + afl->in_scratch_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), len); + memcpy(afl->in_scratch_buf, in_buf, split_at); + memcpy(afl->in_scratch_buf + split_at, new_buf, len - split_at); + in_buf = afl->in_scratch_buf; + out_buf = afl_realloc(AFL_BUF_PARAM(out), len); if (unlikely(!out_buf)) { PFATAL("alloc"); } memcpy(out_buf, in_buf, len); @@ -4569,7 +4472,7 @@ pacemaker_fuzzing: // if (afl->queue_cur->favored) --afl->pending_favored; // } - munmap(orig_in, afl->queue_cur->len); + orig_in = NULL; if (afl->key_puppet == 1) { diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index f224d851..c634328f 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -31,11 +31,12 @@ inline u32 select_next_queue_entry(afl_state_t *afl) { - u32 s = rand_below(afl, afl->queued_paths); + u32 s = rand_below(afl, afl->queued_paths); double p = rand_next_percent(afl); /* fprintf(stderr, "select: p=%f s=%u ... p < prob[s]=%f ? s=%u : alias[%u]=%u" - " ==> %u\n", p, s, afl->alias_probability[s], s, s, afl->alias_table[s], p < afl->alias_probability[s] ? s : afl->alias_table[s]); + " ==> %u\n", p, s, afl->alias_probability[s], s, s, afl->alias_table[s], p < + afl->alias_probability[s] ? s : afl->alias_table[s]); */ return (p < afl->alias_probability[s] ? s : afl->alias_table[s]); @@ -55,7 +56,7 @@ void create_alias_table(afl_state_t *afl) { int * S = (u32 *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32)); int * L = (u32 *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32)); - if (!P || !S || !L) FATAL("could not aquire memory for alias table"); + if (!P || !S || !L) { FATAL("could not aquire memory for alias table"); } memset((void *)afl->alias_table, 0, n * sizeof(u32)); memset((void *)afl->alias_probability, 0, n * sizeof(double)); @@ -65,7 +66,7 @@ void create_alias_table(afl_state_t *afl) { struct queue_entry *q = afl->queue_buf[i]; - if (!q->disabled) q->perf_score = calculate_score(afl, q); + if (!q->disabled) { q->perf_score = calculate_score(afl, q); } sum += q->perf_score; @@ -74,19 +75,23 @@ void create_alias_table(afl_state_t *afl) { for (i = 0; i < n; i++) { struct queue_entry *q = afl->queue_buf[i]; - - P[i] = q->perf_score * n / sum; + P[i] = (q->perf_score * n) / sum; } int nS = 0, nL = 0, s; for (s = (s32)n - 1; s >= 0; --s) { - if (P[s] < 1) + if (P[s] < 1) { + S[nS++] = s; - else + + } else { + L[nL++] = s; + } + } while (nS && nL) { @@ -96,11 +101,16 @@ void create_alias_table(afl_state_t *afl) { afl->alias_probability[a] = P[a]; afl->alias_table[a] = g; P[g] = P[g] + P[a] - 1; - if (P[g] < 1) + if (P[g] < 1) { + S[nS++] = g; - else + + } else { + L[nL++] = g; + } + } while (nL) @@ -110,11 +120,10 @@ void create_alias_table(afl_state_t *afl) { afl->alias_probability[S[--nS]] = 1; /* - fprintf(stderr, " %-3s %-3s %-9s %-9s\n", "entry", "alias", "prob", "perf"); - for (u32 i = 0; i < n; ++i) - fprintf(stderr, " %3i %3i %9.7f %9.7f\n", i, afl->alias_table[i], - afl->alias_probability[i], afl->queue_buf[i]->perf_score); - + fprintf(stderr, " entry alias probability perf_score\n"); + for (u32 i = 0; i < n; ++i) + fprintf(stderr, " %5u %5u %11u %0.9f\n", i, afl->alias_table[i], + afl->alias_probability[i], afl->queue_buf[i]->perf_score); */ } @@ -860,3 +869,131 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { } +void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q, + u32 old_len) { + + if (likely(q->testcase_buf)) { + + free(q->testcase_buf); + int fd = open(q->fname, O_RDONLY); + + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); } + + u32 len = q->len; + q->testcase_buf = malloc(len); + + if (unlikely(!q->testcase_buf)) { + + PFATAL("Unable to mmap '%s' with len %d", q->fname, len); + + } + + close(fd); + afl->q_testcase_cache_size = afl->q_testcase_cache_size + q->len - old_len; + + } + +} + +/* Returns the testcase buf from the file behind this queue entry. + Increases the refcount. */ +inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { + + u32 len = q->len; + + /* first handle if no testcase cache is configured */ + + if (unlikely(!afl->q_testcase_max_cache_size)) { + + u8 *buf; + + if (q == afl->queue_cur) { + + buf = afl_realloc((void **)&afl->testcase_buf, len); + + } else { + + buf = afl_realloc((void **)&afl->splicecase_buf, len); + + } + + if (unlikely(!buf)) { + + PFATAL("Unable to malloc '%s' with len %u", q->fname, len); + + } + + int fd = open(q->fname, O_RDONLY); + + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); } + + ck_read(fd, buf, len, q->fname); + close(fd); + return buf; + + } + + /* now handle the testcase cache */ + + if (unlikely(!q->testcase_buf)) { + + /* Buf not cached, let's load it */ + u32 tid = 0; + + while (unlikely(afl->q_testcase_cache_size + len >= + afl->q_testcase_max_cache_size || + afl->q_testcase_cache_count >= TESTCASE_ENTRIES - 1)) { + + /* Cache full. We neet to evict one to map one. + Get a random one which is not in use */ + + do { + + tid = rand_below(afl, afl->q_testcase_max_cache_count); + + } while (afl->q_testcase_cache[tid] == NULL || + + afl->q_testcase_cache[tid] == afl->queue_cur); + + struct queue_entry *old_cached = afl->q_testcase_cache[tid]; + free(old_cached->testcase_buf); + old_cached->testcase_buf = NULL; + afl->q_testcase_cache_size -= old_cached->len; + afl->q_testcase_cache[tid] = NULL; + --afl->q_testcase_cache_count; + + } + + while (likely(afl->q_testcase_cache[tid] != NULL)) + ++tid; + + /* Map the test case into memory. */ + + int fd = open(q->fname, O_RDONLY); + + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); } + + q->testcase_buf = malloc(len); + + if (unlikely(!q->testcase_buf)) { + + PFATAL("Unable to malloc '%s' with len %u", q->fname, len); + + } + + ck_read(fd, q->testcase_buf, len, q->fname); + close(fd); + + /* Register testcase as cached */ + afl->q_testcase_cache[tid] = q; + afl->q_testcase_cache_size += q->len; + ++afl->q_testcase_cache_count; + if (tid >= afl->q_testcase_max_cache_count) + afl->q_testcase_max_cache_count = tid + 1; + + } + + return q->testcase_buf; + +} + diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index ee22b0f6..ab870319 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -692,6 +692,8 @@ void sync_fuzzers(afl_state_t *afl) { u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { + u32 orig_len = q->len; + /* Custom mutator trimmer */ if (afl->custom_mutators_count) { @@ -709,6 +711,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { }); + if (orig_len != q->len) { queue_testcase_retake(afl, q, orig_len); } + if (custom_trimmed) return trimmed_case; } @@ -842,6 +846,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { close(fd); + if (orig_len != q->len) queue_testcase_retake(afl, q, orig_len); + memcpy(afl->fsrv.trace_bits, afl->clean_trace, afl->fsrv.map_size); update_bitmap_score(afl, q); diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index a0a2795e..0824b77f 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -103,6 +103,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->stats_avg_exec = -1; afl->skip_deterministic = 1; afl->use_splicing = 1; + afl->q_testcase_max_cache_size = TESTCASE_CACHE * 1024000; #ifdef HAVE_AFFINITY afl->cpu_aff = -1; /* Selected CPU core */ @@ -353,6 +354,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_forksrv_init_tmout = (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_TESTCACHE_SIZE", + + afl_environment_variable_len)) { + + afl->afl_env.afl_testcache_size = + (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_STATSD_HOST", afl_environment_variable_len)) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 76f24977..4f0cab4c 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -165,6 +165,8 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, "edges_found : %u\n" "var_byte_count : %u\n" "havoc_expansion : %u\n" + "testcache_size : %llu\n" + "testcache_count : %u\n" "afl_banner : %s\n" "afl_version : " VERSION "\n" @@ -198,8 +200,9 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, #else -1, #endif - t_bytes, afl->var_byte_count, afl->expand_havoc, afl->use_banner, - afl->unicorn_mode ? "unicorn" : "", + t_bytes, afl->var_byte_count, afl->expand_havoc, + afl->q_testcase_cache_size, afl->q_testcase_cache_count, + afl->use_banner, afl->unicorn_mode ? "unicorn" : "", afl->fsrv.qemu_mode ? "qemu " : "", afl->non_instrumented_mode ? " non_instrumented " : "", afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "", diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 6498eb30..a59abb7d 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -196,11 +196,13 @@ static void usage(u8 *argv0, int more_help) { "AFL_SKIP_BIN_CHECK: skip the check, if the target is an executable\n" "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n" "AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n" - "AFL_STATSD: enables StatsD metrics collection" - "AFL_STATSD_HOST: change default statsd host (default 127.0.0.1)" - "AFL_STATSD_PORT: change default statsd port (default: 8125)" - "AFL_STATSD_TAGS_FLAVOR: change default statsd tags format (default will disable tags)." - " Supported formats are: 'dogstatsd', 'librato', 'signalfx' and 'influxdb'" + "AFL_STATSD: enables StatsD metrics collection\n" + "AFL_STATSD_HOST: change default statsd host (default 127.0.0.1)\n" + "AFL_STATSD_PORT: change default statsd port (default: 8125)\n" + "AFL_STATSD_TAGS_FLAVOR: set statsd tags format (default: disable tags)\n" + " Supported formats are: 'dogstatsd', 'librato', 'signalfx'\n" + " and 'influxdb'\n" + "AFL_TESTCACHE_SIZE: use a cache for testcases, improves performance (in MB)\n" "AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n" //"AFL_PERSISTENT: not supported anymore -> no effect, just a warning\n" //"AFL_DEFER_FORKSRV: not supported anymore -> no effect, just a warning\n" @@ -885,7 +887,7 @@ int main(int argc, char **argv_orig, char **envp) { auto_sync = 1; afl->sync_id = ck_strdup("default"); afl->is_secondary_node = 1; - OKF("no -M/-S set, autoconfiguring for \"-S %s\"", afl->sync_id); + OKF("No -M/-S set, autoconfiguring for \"-S %s\"", afl->sync_id); } @@ -1006,6 +1008,21 @@ int main(int argc, char **argv_orig, char **envp) { } + if (afl->afl_env.afl_testcache_size) { + + afl->q_testcase_max_cache_size = + (u64)atoi(afl->afl_env.afl_testcache_size) * 1024000; + OKF("Enabled testcache with %llu MB", + afl->q_testcase_max_cache_size / 1024000); + + } else { + + ACTF( + "No testcache was configured. it is recommended to use a testcache, it " + "improves performance: set AFL_TESTCACHE_SIZE=(value in MB)"); + + } + if (afl->afl_env.afl_forksrv_init_tmout) { afl->fsrv.init_tmout = atoi(afl->afl_env.afl_forksrv_init_tmout); diff --git a/src/afl-performance.c b/src/afl-performance.c index 6fa95dea..e070a05e 100644 --- a/src/afl-performance.c +++ b/src/afl-performance.c @@ -71,7 +71,7 @@ inline uint64_t rand_next(afl_state_t *afl) { inline double rand_next_percent(afl_state_t *afl) { - return (double)(((double)rand_next(afl)) / (double) 0xffffffffffffffff); + return (double)(((double)rand_next(afl)) / (double)0xffffffffffffffff); } -- cgit v1.2.3 From 735e8c39561d3d4d8bae01251e025e52e05472e2 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 14 Oct 2020 17:32:51 +0200 Subject: check for minimum cache size --- src/afl-fuzz.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index a59abb7d..3167b742 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -200,8 +200,8 @@ static void usage(u8 *argv0, int more_help) { "AFL_STATSD_HOST: change default statsd host (default 127.0.0.1)\n" "AFL_STATSD_PORT: change default statsd port (default: 8125)\n" "AFL_STATSD_TAGS_FLAVOR: set statsd tags format (default: disable tags)\n" - " Supported formats are: 'dogstatsd', 'librato', 'signalfx'\n" - " and 'influxdb'\n" + " Supported formats are: 'dogstatsd', 'librato',\n" + " 'signalfx' and 'influxdb'\n" "AFL_TESTCACHE_SIZE: use a cache for testcases, improves performance (in MB)\n" "AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n" //"AFL_PERSISTENT: not supported anymore -> no effect, just a warning\n" @@ -1012,15 +1012,26 @@ int main(int argc, char **argv_orig, char **envp) { afl->q_testcase_max_cache_size = (u64)atoi(afl->afl_env.afl_testcache_size) * 1024000; - OKF("Enabled testcache with %llu MB", - afl->q_testcase_max_cache_size / 1024000); - } else { + } + + if (!afl->q_testcase_max_cache_size) { ACTF( "No testcache was configured. it is recommended to use a testcache, it " "improves performance: set AFL_TESTCACHE_SIZE=(value in MB)"); + } else if (afl->q_testcase_max_cache_size < 2 * MAX_FILE) { + + FATAL("AFL_TESTCACHE_SIZE must be set to %u or more, or 0 to disable", + (2 * MAX_FILE) % 1024000 ? 1 + ((2 * MAX_FILE) / 1024000) + : (2 * MAX_FILE) / 1024000); + + } else { + + OKF("Enabled testcache with %llu MB", + afl->q_testcase_max_cache_size / 1024000); + } if (afl->afl_env.afl_forksrv_init_tmout) { -- cgit v1.2.3 From 638bf19b651864bdc6ec801f87123d08f92af04e Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 14 Oct 2020 17:14:36 +0100 Subject: DragonFlyBSD build fix proposal. --- src/afl-fuzz-init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 607b652f..13e42e03 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -272,7 +272,7 @@ void bind_to_free_cpu(afl_state_t *afl) { #elif defined(__DragonFly__) - if (procs[i].kp_lwp.kl_cpuid < sizeof(cpu_used) && + if (procs[i].kp_lwp.kl_cpuid < (s32)sizeof(cpu_used) && procs[i].kp_lwp.kl_pctcpu > 10) cpu_used[procs[i].kp_lwp.kl_cpuid] = 1; -- cgit v1.2.3 From 24e0c9cf65428efce181eaecc8c69ee030b8dfcc Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 15 Oct 2020 10:22:40 +0200 Subject: add missing swap bufs --- src/afl-fuzz-one.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 154e4b45..9c5e2e3c 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2465,6 +2465,7 @@ retry_splicing: afl->in_scratch_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), len); memcpy(afl->in_scratch_buf, in_buf, split_at); memcpy(afl->in_scratch_buf + split_at, new_buf, len - split_at); + afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); in_buf = afl->in_scratch_buf; out_buf = afl_realloc(AFL_BUF_PARAM(out), len); -- cgit v1.2.3 From 0139b8cdcb81ec1ed873f182946b686a04f46ac6 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 15 Oct 2020 10:28:11 +0200 Subject: add missing swap bufs --- src/afl-fuzz-one.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 9c5e2e3c..cbfbbc58 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -4434,6 +4434,7 @@ pacemaker_fuzzing: afl->in_scratch_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), len); memcpy(afl->in_scratch_buf, in_buf, split_at); memcpy(afl->in_scratch_buf + split_at, new_buf, len - split_at); + afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); in_buf = afl->in_scratch_buf; out_buf = afl_realloc(AFL_BUF_PARAM(out), len); -- cgit v1.2.3 From d1e18f9edf43dc71ab81619eeed7a0f5fa0bb15f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 15 Oct 2020 12:20:33 +0200 Subject: fix afl_swap_bufs usage? --- src/afl-fuzz-one.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index cbfbbc58..1899193e 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2149,7 +2149,6 @@ havoc_stage: temp_len - clone_to); afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); - out_buf = new_buf; temp_len += clone_len; } @@ -2346,7 +2345,6 @@ havoc_stage: temp_len - clone_to); afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); - out_buf = temp_buf; temp_len += clone_len; } @@ -2465,8 +2463,8 @@ retry_splicing: afl->in_scratch_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), len); memcpy(afl->in_scratch_buf, in_buf, split_at); memcpy(afl->in_scratch_buf + split_at, new_buf, len - split_at); - afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); in_buf = afl->in_scratch_buf; + afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); out_buf = afl_realloc(AFL_BUF_PARAM(out), len); if (unlikely(!out_buf)) { PFATAL("alloc"); } @@ -4142,7 +4140,6 @@ pacemaker_fuzzing: temp_len - clone_to); afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); - out_buf = new_buf; temp_len += clone_len; MOpt_globals.cycles_v2[STAGE_Clone75] += 1; @@ -4434,8 +4431,8 @@ pacemaker_fuzzing: afl->in_scratch_buf = afl_realloc(AFL_BUF_PARAM(in_scratch), len); memcpy(afl->in_scratch_buf, in_buf, split_at); memcpy(afl->in_scratch_buf + split_at, new_buf, len - split_at); - afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); in_buf = afl->in_scratch_buf; + afl_swap_bufs(AFL_BUF_PARAM(in), AFL_BUF_PARAM(in_scratch)); out_buf = afl_realloc(AFL_BUF_PARAM(out), len); if (unlikely(!out_buf)) { PFATAL("alloc"); } -- cgit v1.2.3 From ea0851c654285cc33ac25637d2054044ee6ee2ee Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 15 Oct 2020 12:54:18 +0200 Subject: fix previous commit --- src/afl-fuzz-one.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 1899193e..02550d36 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2148,6 +2148,7 @@ havoc_stage: memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, temp_len - clone_to); + out_buf = new_buf; afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); temp_len += clone_len; @@ -2344,6 +2345,7 @@ havoc_stage: memcpy(temp_buf + clone_to + clone_len, out_buf + clone_to, temp_len - clone_to); + out_buf = temp_buf; afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); temp_len += clone_len; @@ -4139,6 +4141,7 @@ pacemaker_fuzzing: memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, temp_len - clone_to); + out_buf = new_buf; afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); temp_len += clone_len; MOpt_globals.cycles_v2[STAGE_Clone75] += 1; -- cgit v1.2.3 From 0f8529a3db242131486cc3bf4a66c024c2b3e126 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 15 Oct 2020 15:22:40 +0200 Subject: prepare halloween fuzzbench run --- src/afl-fuzz-queue.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index c634328f..38d7f77e 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -120,10 +120,11 @@ void create_alias_table(afl_state_t *afl) { afl->alias_probability[S[--nS]] = 1; /* - fprintf(stderr, " entry alias probability perf_score\n"); + fprintf(stderr, " entry alias probability perf_score filename\n"); for (u32 i = 0; i < n; ++i) - fprintf(stderr, " %5u %5u %11u %0.9f\n", i, afl->alias_table[i], - afl->alias_probability[i], afl->queue_buf[i]->perf_score); + fprintf(stderr, " %5u %5u %11u %0.9f %s\n", i, afl->alias_table[i], + afl->alias_probability[i], afl->queue_buf[i]->perf_score, + afl->queue_buf[i]->fname); */ } -- cgit v1.2.3 From 354bda28465588e424c0a93b413af01a603191ce Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 15 Oct 2020 15:33:47 +0200 Subject: fix reget of testcase after trim --- src/afl-fuzz-queue.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 38d7f77e..095a391f 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -875,22 +875,27 @@ void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q, if (likely(q->testcase_buf)) { - free(q->testcase_buf); - int fd = open(q->fname, O_RDONLY); + u32 len = q->len; - if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); } + if (len != old_len) { - u32 len = q->len; - q->testcase_buf = malloc(len); + afl->q_testcase_cache_size = + afl->q_testcase_cache_size + q->len - old_len; + q->testcase_buf = realloc(q->testcase_buf, len); + if (unlikely(!q->testcase_buf)) { - if (unlikely(!q->testcase_buf)) { + PFATAL("Unable to malloc '%s' with len %d", q->fname, len); - PFATAL("Unable to mmap '%s' with len %d", q->fname, len); + } } + int fd = open(q->fname, O_RDONLY); + + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); } + + ck_read(fd, q->testcase_buf, len, q->fname); close(fd); - afl->q_testcase_cache_size = afl->q_testcase_cache_size + q->len - old_len; } -- cgit v1.2.3 From f41aafa4f7aa446c3cb1cbe6d77364cf32a6c6cb Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 15 Oct 2020 15:48:39 +0200 Subject: retake from mem if possible --- src/afl-fuzz-queue.c | 39 ++++++++++++++++++++++++++++++++++----- src/afl-fuzz-run.c | 8 ++++++-- 2 files changed, 40 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 095a391f..92b722f6 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -870,8 +870,10 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { } -void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q, - u32 old_len) { +/* after a custom trim we need to reload the testcase from disk */ + +inline void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q, + u32 old_len) { if (likely(q->testcase_buf)) { @@ -879,9 +881,9 @@ void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q, if (len != old_len) { - afl->q_testcase_cache_size = - afl->q_testcase_cache_size + q->len - old_len; + afl->q_testcase_cache_size = afl->q_testcase_cache_size + len - old_len; q->testcase_buf = realloc(q->testcase_buf, len); + if (unlikely(!q->testcase_buf)) { PFATAL("Unable to malloc '%s' with len %d", q->fname, len); @@ -901,8 +903,35 @@ void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q, } +/* after a normal trim we need to replace the testcase with the new data */ + +inline void queue_testcase_retake_mem(afl_state_t *afl, struct queue_entry *q, + u8 *in, u32 len, u32 old_len) { + + if (likely(q->testcase_buf)) { + + if (len != old_len) { + + afl->q_testcase_cache_size = afl->q_testcase_cache_size + len - old_len; + q->testcase_buf = realloc(q->testcase_buf, len); + + if (unlikely(!q->testcase_buf)) { + + PFATAL("Unable to malloc '%s' with len %d", q->fname, len); + + } + + } + + memcpy(q->testcase_buf, in, len); + + } + +} + /* Returns the testcase buf from the file behind this queue entry. Increases the refcount. */ + inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { u32 len = q->len; @@ -913,7 +942,7 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { u8 *buf; - if (q == afl->queue_cur) { + if (unlikely(q == afl->queue_cur)) { buf = afl_realloc((void **)&afl->testcase_buf, len); diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index ab870319..dfd3abfb 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -711,7 +711,11 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { }); - if (orig_len != q->len) { queue_testcase_retake(afl, q, orig_len); } + if (orig_len != q->len || custom_trimmed) { + + queue_testcase_retake(afl, q, orig_len); + + } if (custom_trimmed) return trimmed_case; @@ -846,7 +850,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { close(fd); - if (orig_len != q->len) queue_testcase_retake(afl, q, orig_len); + queue_testcase_retake_mem(afl, q, in_buf, q->len, orig_len); memcpy(afl->fsrv.trace_bits, afl->clean_trace, afl->fsrv.map_size); update_bitmap_score(afl, q); -- cgit v1.2.3 From ee66cd7b27315b2003b005d2f215191d5db954c8 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 15 Oct 2020 17:08:45 +0200 Subject: testcache_size = 2 ok fix --- src/afl-fuzz.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 3167b742..9a82edeb 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1011,7 +1011,7 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->afl_env.afl_testcache_size) { afl->q_testcase_max_cache_size = - (u64)atoi(afl->afl_env.afl_testcache_size) * 1024000; + (u64)atoi(afl->afl_env.afl_testcache_size) * 1048576; } @@ -1024,8 +1024,8 @@ int main(int argc, char **argv_orig, char **envp) { } else if (afl->q_testcase_max_cache_size < 2 * MAX_FILE) { FATAL("AFL_TESTCACHE_SIZE must be set to %u or more, or 0 to disable", - (2 * MAX_FILE) % 1024000 ? 1 + ((2 * MAX_FILE) / 1024000) - : (2 * MAX_FILE) / 1024000); + (2 * MAX_FILE) % 1024000 == 0 ? (2 * MAX_FILE) / 1048576 + : 1 + ((2 * MAX_FILE) / 1048576)); } else { -- cgit v1.2.3 From b82e9ad3dbf3068223498445ff5e7f4ea63ce6f7 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 16 Oct 2020 09:16:35 +0200 Subject: next afl-showmap fix attempt --- src/afl-showmap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 545bfaa9..822e62df 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -742,8 +742,10 @@ int main(int argc, char **argv_orig, char **envp) { case 'f': // only in here to avoid a compiler warning for use_stdin - fsrv->use_stdin = 0; FATAL("Option -f is not supported in afl-showmap"); + // currently not reached: + fsrv->use_stdin = 0; + fsrv->out_file = strdup(optarg); break; @@ -1015,6 +1017,7 @@ int main(int argc, char **argv_orig, char **envp) { alloc_printf("%s/.afl-showmap-temp-%u", use_dir, (u32)getpid()); unlink(stdin_file); atexit(at_exit_handler); + afl->fsrv.out_file = stdin_file; fsrv->out_fd = open(stdin_file, O_RDWR | O_CREAT | O_EXCL, 0600); if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", out_file); } -- cgit v1.2.3 From d5c3b4bafdae8a68e7f63c0afdd1cc5820636f2d Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 16 Oct 2020 09:35:35 +0200 Subject: directly add new queue to cache --- src/afl-fuzz-bitmap.c | 6 ++++++ src/afl-fuzz-queue.c | 43 ++++++++++++++++++++++++++++++++++++++++++- src/afl-showmap.c | 2 +- 3 files changed, 49 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index a22223b9..2653b9fd 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -623,6 +623,12 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { ck_write(fd, mem, len, queue_fn); close(fd); + if (likely(afl->q_testcase_max_cache_size)) { + + queue_testcase_store_mem(afl, afl->queue_top, mem); + + } + keeping = 1; } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 92b722f6..f8034ebd 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -1021,7 +1021,7 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { /* Register testcase as cached */ afl->q_testcase_cache[tid] = q; - afl->q_testcase_cache_size += q->len; + afl->q_testcase_cache_size += len; ++afl->q_testcase_cache_count; if (tid >= afl->q_testcase_max_cache_count) afl->q_testcase_max_cache_count = tid + 1; @@ -1032,3 +1032,44 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { } +/* Adds the new queue entry to the cache. */ + +inline void queue_testcase_store_mem(afl_state_t *afl, struct queue_entry *q, + u8 *mem) { + + u32 len = q->len; + + if (unlikely(afl->q_testcase_cache_size + len >= + afl->q_testcase_max_cache_size || + afl->q_testcase_cache_count >= TESTCASE_ENTRIES - 1)) { + + return; + + } + + u32 tid = 0; + + while (likely(afl->q_testcase_cache[tid] != NULL)) + ++tid; + + /* Map the test case into memory. */ + + q->testcase_buf = malloc(len); + + if (unlikely(!q->testcase_buf)) { + + PFATAL("Unable to malloc '%s' with len %u", q->fname, len); + + } + + memcpy(q->testcase_buf, mem, len); + + /* Register testcase as cached */ + afl->q_testcase_cache[tid] = q; + afl->q_testcase_cache_size += len; + ++afl->q_testcase_cache_count; + if (tid >= afl->q_testcase_max_cache_count) + afl->q_testcase_max_cache_count = tid + 1; + +} + diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 822e62df..6213c447 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1017,7 +1017,7 @@ int main(int argc, char **argv_orig, char **envp) { alloc_printf("%s/.afl-showmap-temp-%u", use_dir, (u32)getpid()); unlink(stdin_file); atexit(at_exit_handler); - afl->fsrv.out_file = stdin_file; + fsrv->out_file = stdin_file; fsrv->out_fd = open(stdin_file, O_RDWR | O_CREAT | O_EXCL, 0600); if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", out_file); } -- cgit v1.2.3 From fcea01a8ea7ec507b675d839035eb0fed2f06867 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 17 Oct 2020 11:38:55 +0200 Subject: add eviction stat --- src/afl-fuzz-queue.c | 1 + src/afl-fuzz-stats.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index f8034ebd..e0df7206 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -996,6 +996,7 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { afl->q_testcase_cache_size -= old_cached->len; afl->q_testcase_cache[tid] = NULL; --afl->q_testcase_cache_count; + ++afl->q_testcase_evictions; } diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 4f0cab4c..d213d054 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -167,6 +167,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, "havoc_expansion : %u\n" "testcache_size : %llu\n" "testcache_count : %u\n" + "testcache_evict : %u\n" "afl_banner : %s\n" "afl_version : " VERSION "\n" @@ -202,7 +203,8 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, #endif t_bytes, afl->var_byte_count, afl->expand_havoc, afl->q_testcase_cache_size, afl->q_testcase_cache_count, - afl->use_banner, afl->unicorn_mode ? "unicorn" : "", + afl->q_testcase_evictions, afl->use_banner, + afl->unicorn_mode ? "unicorn" : "", afl->fsrv.qemu_mode ? "qemu " : "", afl->non_instrumented_mode ? " non_instrumented " : "", afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "", -- cgit v1.2.3 From d8a058bf592a040256bb4b0a1ff9dcb97a8e3eda Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 17 Oct 2020 14:34:14 +0200 Subject: fix AFL_CMIN_CRASHES_ONLY=1 afl-showmap --- src/afl-showmap.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 6213c447..bd0d1a29 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -209,6 +209,13 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { if (!outfile) { FATAL("Output filename not set (Bug in AFL++?)"); } + if (cmin_mode && (fsrv->last_run_timed_out + || (!caa && child_crashed != cco))) { + + return ret; + + } + if (!strncmp(outfile, "/dev/", 5)) { fd = open(outfile, O_WRONLY); @@ -255,9 +262,6 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { if (cmin_mode) { - if (fsrv->last_run_timed_out) { break; } - if (!caa && child_crashed != cco) { break; } - fprintf(f, "%u%u\n", fsrv->trace_bits[i], i); } else { @@ -292,6 +296,37 @@ static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, u8 *mem, classify_counts(fsrv); + if (!quiet_mode) { SAYF(cRST "-- Program output ends --\n"); } + + if (!fsrv->last_run_timed_out && !stop_soon && WIFSIGNALED(fsrv->child_status)) { + + child_crashed = 1; + + } else { + + child_crashed = 0; + + } + + if (!quiet_mode) { + + if (fsrv->last_run_timed_out) { + + SAYF(cLRD "\n+++ Program timed off +++\n" cRST); + + } else if (stop_soon) { + + SAYF(cLRD "\n+++ Program aborted by user +++\n" cRST); + + } else if (child_crashed) { + + SAYF(cLRD "\n+++ Program killed by signal %u +++\n" cRST, + WTERMSIG(fsrv->child_status)); + + } + + } + if (stop_soon) { SAYF(cRST cLRD "\n+++ afl-showmap folder mode aborted by user +++\n" cRST); @@ -1156,8 +1191,17 @@ int main(int argc, char **argv_orig, char **envp) { afl_shm_deinit(&shm); if (fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz); - u32 ret = child_crashed * 2 + fsrv->last_run_timed_out; + u32 ret; + + if (cmin_mode && !!getenv("AFL_CMIN_CRASHES_ONLY")) { + + ret = fsrv->last_run_timed_out; + } else { + + ret = child_crashed * 2 + fsrv->last_run_timed_out; + + } if (fsrv->target_path) { ck_free(fsrv->target_path); } afl_fsrv_deinit(fsrv); -- cgit v1.2.3 From ac1c3b87015dd2c9b1bae0198f7925816aa63aec Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 19 Oct 2020 11:34:57 +0200 Subject: mini improvements --- src/afl-fuzz-one.c | 2 +- src/afl-fuzz-queue.c | 8 ++++---- src/afl-fuzz.c | 56 +++++++++++++++++++++++++++------------------------- src/afl-showmap.c | 10 ++++++---- 4 files changed, 40 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 02550d36..1e63abc7 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2540,7 +2540,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { #else - if (afl->pending_favored) { + if (likely(afl->pending_favored)) { /* If we have any favored, non-fuzzed new arrivals in the queue, possibly skip to them at the expense of already-fuzzed or non-favored diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index e0df7206..7f157121 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -179,9 +179,9 @@ void mark_as_variable(afl_state_t *afl, struct queue_entry *q) { void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) { - u8 fn[PATH_MAX]; + if (likely(state == q->fs_redundant)) { return; } - if (state == q->fs_redundant) { return; } + u8 fn[PATH_MAX]; q->fs_redundant = state; @@ -521,13 +521,13 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { void cull_queue(afl_state_t *afl) { + if (likely(!afl->score_changed || afl->non_instrumented_mode)) { return; } + struct queue_entry *q; u32 len = (afl->fsrv.map_size >> 3); u32 i; u8 * temp_v = afl->map_tmp_buf; - if (afl->non_instrumented_mode || !afl->score_changed) { return; } - afl->score_changed = 0; memset(temp_v, 255, len); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 9a82edeb..7215ecec 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1378,10 +1378,9 @@ int main(int argc, char **argv_orig, char **envp) { u32 runs_in_current_cycle = (u32)-1; u32 prev_queued_paths = 0; + u8 skipped_fuzz; - while (1) { - - u8 skipped_fuzz; + while (likely(!afl->stop_soon)) { cull_queue(afl); @@ -1418,8 +1417,8 @@ int main(int argc, char **argv_orig, char **envp) { /* If we had a full queue cycle with no new finds, try recombination strategies next. */ - if (afl->queued_paths == prev_queued && - (get_cur_time() - afl->start_time) >= 3600) { + if (unlikely(afl->queued_paths == prev_queued && + (get_cur_time() - afl->start_time) >= 3600)) { if (afl->use_splicing) { @@ -1534,46 +1533,49 @@ int main(int argc, char **argv_orig, char **envp) { } - if (likely(!afl->old_seed_selection)) { + ++runs_in_current_cycle; - ++runs_in_current_cycle; - if (unlikely(prev_queued_paths < afl->queued_paths)) { + do { - // we have new queue entries since the last run, recreate alias table - prev_queued_paths = afl->queued_paths; - create_alias_table(afl); + if (likely(!afl->old_seed_selection)) { - } + if (unlikely(prev_queued_paths < afl->queued_paths)) { - afl->current_entry = select_next_queue_entry(afl); - afl->queue_cur = afl->queue_buf[afl->current_entry]; + // we have new queue entries since the last run, recreate alias table + prev_queued_paths = afl->queued_paths; + create_alias_table(afl); - } + } - skipped_fuzz = fuzz_one(afl); + afl->current_entry = select_next_queue_entry(afl); + afl->queue_cur = afl->queue_buf[afl->current_entry]; - if (!skipped_fuzz && !afl->stop_soon && afl->sync_id) { + } - if (unlikely(afl->is_main_node)) { + skipped_fuzz = fuzz_one(afl); - if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) { sync_fuzzers(afl); } + if (unlikely(!afl->stop_soon && exit_1)) { afl->stop_soon = 2; } - } else { + if (unlikely(afl->old_seed_selection)) { - if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); } + afl->queue_cur = afl->queue_cur->next; + ++afl->current_entry; } - } + } while (skipped_fuzz && afl->queue_cur && !afl->stop_soon); - if (!afl->stop_soon && exit_1) { afl->stop_soon = 2; } + if (!afl->stop_soon && afl->sync_id) { - if (afl->stop_soon) { break; } + if (unlikely(afl->is_main_node)) { - if (unlikely(afl->old_seed_selection)) { + if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) { sync_fuzzers(afl); } - afl->queue_cur = afl->queue_cur->next; - ++afl->current_entry; + } else { + + if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); } + + } } diff --git a/src/afl-showmap.c b/src/afl-showmap.c index bd0d1a29..4b357254 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -209,10 +209,10 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { if (!outfile) { FATAL("Output filename not set (Bug in AFL++?)"); } - if (cmin_mode && (fsrv->last_run_timed_out - || (!caa && child_crashed != cco))) { + if (cmin_mode && + (fsrv->last_run_timed_out || (!caa && child_crashed != cco))) { - return ret; + return ret; } @@ -298,7 +298,8 @@ static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, u8 *mem, if (!quiet_mode) { SAYF(cRST "-- Program output ends --\n"); } - if (!fsrv->last_run_timed_out && !stop_soon && WIFSIGNALED(fsrv->child_status)) { + if (!fsrv->last_run_timed_out && !stop_soon && + WIFSIGNALED(fsrv->child_status)) { child_crashed = 1; @@ -1202,6 +1203,7 @@ int main(int argc, char **argv_orig, char **envp) { ret = child_crashed * 2 + fsrv->last_run_timed_out; } + if (fsrv->target_path) { ck_free(fsrv->target_path); } afl_fsrv_deinit(fsrv); -- cgit v1.2.3 From d0cdbc48aebf88bc0cc519db553ca762f794296e Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 20 Oct 2020 00:07:40 +0200 Subject: always close file descriptor when opened, use standard types --- src/afl-fuzz-queue.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 7f157121..1bda0835 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -211,13 +211,16 @@ static u8 check_if_text(struct queue_entry *q) { if (q->len < AFL_TXT_MIN_LEN) return 0; u8 buf[MAX_FILE]; - s32 fd, len = q->len, offset = 0, ascii = 0, utf8 = 0, comp; + int fd; + u32 len = q->len, offset = 0, ascii = 0, utf8 = 0; + ssize_t comp; if (len >= MAX_FILE) len = MAX_FILE - 1; if ((fd = open(q->fname, O_RDONLY)) < 0) return 0; - if ((comp = read(fd, buf, len)) != len) return 0; - buf[len] = 0; + comp = read(fd, buf, len); close(fd); + if (comp != (ssize_t)len) return 0; + buf[len] = 0; while (offset < len) { -- cgit v1.2.3 From 73c0e1357fa33276ca0a0ee63aacc933aa9ceac5 Mon Sep 17 00:00:00 2001 From: bigredb Date: Tue, 20 Oct 2020 05:16:34 -0700 Subject: qemu argv index was still wrong --- src/afl-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index ddae2ac1..19c9419b 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -146,7 +146,7 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { u8 * tmp, *cp = NULL, *rsl, *own_copy; memcpy(&new_argv[3], &argv[1], (int)(sizeof(char *)) * (argc - 1)); - new_argv[argc + 2] = NULL; + new_argv[argc + 3] = NULL; new_argv[2] = *target_path_p; new_argv[1] = "--"; -- cgit v1.2.3 From 982260c134e7b373a6ec102fe2ef9904d342fa20 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Tue, 20 Oct 2020 20:48:33 +0200 Subject: fix timeout bug in read_s32_timed on non linux OSes --- src/afl-forkserver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 33b16817..df300950 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -140,7 +140,7 @@ read_s32_timed(s32 fd, s32 *buf, u32 timeout_ms, volatile u8 *stop_soon_p) { timeout.tv_sec = (timeout_ms / 1000); timeout.tv_usec = (timeout_ms % 1000) * 1000; #if !defined(__linux__) - u64 read_start = get_cur_time_us(); + u32 read_start = get_cur_time_us(); #endif /* set exceptfds as well to return when a child exited/closed the pipe. */ @@ -166,7 +166,7 @@ restart_select: timeout_ms, ((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000))); #else - u32 exec_ms = MIN(timeout_ms, get_cur_time_us() - read_start); + u32 exec_ms = MIN(timeout_ms, (get_cur_time_us() - read_start) / 1000); #endif // ensure to report 1 ms has passed (0 is an error) -- cgit v1.2.3 From 8d75c089384a0975e39e54f3ba23c37a6101b61c Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 22 Oct 2020 15:48:09 +0200 Subject: change queue cache algo --- src/afl-fuzz-queue.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 1bda0835..3e6deb0c 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -210,9 +210,9 @@ static u8 check_if_text(struct queue_entry *q) { if (q->len < AFL_TXT_MIN_LEN) return 0; - u8 buf[MAX_FILE]; - int fd; - u32 len = q->len, offset = 0, ascii = 0, utf8 = 0; + u8 buf[MAX_FILE]; + int fd; + u32 len = q->len, offset = 0, ascii = 0, utf8 = 0; ssize_t comp; if (len >= MAX_FILE) len = MAX_FILE - 1; @@ -913,7 +913,7 @@ inline void queue_testcase_retake_mem(afl_state_t *afl, struct queue_entry *q, if (likely(q->testcase_buf)) { - if (len != old_len) { + if (likely(len != old_len)) { afl->q_testcase_cache_size = afl->q_testcase_cache_size + len - old_len; q->testcase_buf = realloc(q->testcase_buf, len); @@ -976,17 +976,21 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { if (unlikely(!q->testcase_buf)) { /* Buf not cached, let's load it */ - u32 tid = 0; + u32 tid = afl->q_testcase_max_cache_count; while (unlikely(afl->q_testcase_cache_size + len >= afl->q_testcase_max_cache_size || afl->q_testcase_cache_count >= TESTCASE_ENTRIES - 1)) { - /* Cache full. We neet to evict one to map one. + /* Cache full. We neet to evict one or more to map one. Get a random one which is not in use */ do { + // if the cache (MB) is not enough for the queue then this gets + // undesirable because q_testcase_max_cache_count grows sometimes + // although the number of items in the cache will not change hence + // more and more loops tid = rand_below(afl, afl->q_testcase_max_cache_count); } while (afl->q_testcase_cache[tid] == NULL || @@ -1003,7 +1007,16 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { } - while (likely(afl->q_testcase_cache[tid] != NULL)) + if (tid >= TESTCASE_ENTRIES) { + + // uh we were full, so now we have to search from start + tid = 0; + + } + + // we need this while loop in case there were ever previous evictions but + // not in this call. + while (unlikely(afl->q_testcase_cache[tid] != NULL)) ++tid; /* Map the test case into memory. */ @@ -1047,6 +1060,7 @@ inline void queue_testcase_store_mem(afl_state_t *afl, struct queue_entry *q, afl->q_testcase_max_cache_size || afl->q_testcase_cache_count >= TESTCASE_ENTRIES - 1)) { + // no space? will be loaded regularly later. return; } -- cgit v1.2.3 From c866aef37fcf799506d93b9a47d4eb2b77c75f5b Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 22 Oct 2020 21:07:37 +0200 Subject: maybe enhancement to cache algo --- src/afl-fuzz-queue.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 3e6deb0c..db387c33 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -1004,13 +1004,15 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { afl->q_testcase_cache[tid] = NULL; --afl->q_testcase_cache_count; ++afl->q_testcase_evictions; + if (tid < afl->q_testcase_smallest_free) + afl->q_testcase_smallest_free = tid; } - if (tid >= TESTCASE_ENTRIES) { + if (unlikely(tid >= TESTCASE_ENTRIES)) { // uh we were full, so now we have to search from start - tid = 0; + tid = afl->q_testcase_smallest_free; } @@ -1042,6 +1044,8 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { ++afl->q_testcase_cache_count; if (tid >= afl->q_testcase_max_cache_count) afl->q_testcase_max_cache_count = tid + 1; + if (tid == afl->q_testcase_smallest_free) + afl->q_testcase_smallest_free = tid + 1; } -- cgit v1.2.3 From 0e748ccda713708de6a501d23a58788aba9d0b03 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 23 Oct 2020 14:05:34 +0200 Subject: set max testcache entries automated if not specified by the user --- src/afl-fuzz-queue.c | 11 +++++---- src/afl-fuzz-state.c | 10 +++++++- src/afl-fuzz-stats.c | 2 +- src/afl-fuzz.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 81 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index db387c33..baa80e61 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -978,9 +978,9 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { /* Buf not cached, let's load it */ u32 tid = afl->q_testcase_max_cache_count; - while (unlikely(afl->q_testcase_cache_size + len >= - afl->q_testcase_max_cache_size || - afl->q_testcase_cache_count >= TESTCASE_ENTRIES - 1)) { + while (unlikely( + afl->q_testcase_cache_size + len >= afl->q_testcase_max_cache_size || + afl->q_testcase_cache_count >= afl->q_testcase_max_cache_entries - 1)) { /* Cache full. We neet to evict one or more to map one. Get a random one which is not in use */ @@ -1009,7 +1009,7 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { } - if (unlikely(tid >= TESTCASE_ENTRIES)) { + if (unlikely(tid >= afl->q_testcase_max_cache_entries)) { // uh we were full, so now we have to search from start tid = afl->q_testcase_smallest_free; @@ -1062,7 +1062,8 @@ inline void queue_testcase_store_mem(afl_state_t *afl, struct queue_entry *q, if (unlikely(afl->q_testcase_cache_size + len >= afl->q_testcase_max_cache_size || - afl->q_testcase_cache_count >= TESTCASE_ENTRIES - 1)) { + afl->q_testcase_cache_count >= + afl->q_testcase_max_cache_entries - 1)) { // no space? will be loaded regularly later. return; diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 0824b77f..ae7d410b 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -103,7 +103,8 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->stats_avg_exec = -1; afl->skip_deterministic = 1; afl->use_splicing = 1; - afl->q_testcase_max_cache_size = TESTCASE_CACHE * 1024000; + afl->q_testcase_max_cache_size = TESTCASE_CACHE_SIZE * 1048576UL; + afl->q_testcase_max_cache_entries = 4096; #ifdef HAVE_AFFINITY afl->cpu_aff = -1; /* Selected CPU core */ @@ -361,6 +362,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_testcache_size = (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_TESTCACHE_ENTRIES", + + afl_environment_variable_len)) { + + afl->afl_env.afl_testcache_entries = + (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_STATSD_HOST", afl_environment_variable_len)) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index d213d054..bec90519 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -1028,7 +1028,7 @@ void show_init_stats(afl_state_t *afl) { } - SAYF("\n"); + // SAYF("\n"); if (avg_us > ((afl->fsrv.qemu_mode || afl->unicorn_mode) ? 50000 : 10000)) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 7215ecec..637e1985 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -251,7 +251,7 @@ static int stricmp(char const *a, char const *b) { int main(int argc, char **argv_orig, char **envp) { - s32 opt, i, auto_sync = 0; + s32 opt, i, auto_sync = 0, user_set_cache = 0; u64 prev_queued = 0; u32 sync_interval_cnt = 0, seek_to = 0, show_help = 0, map_size = MAP_SIZE; u8 *extras_dir[4]; @@ -1015,6 +1015,22 @@ int main(int argc, char **argv_orig, char **envp) { } + if (afl->afl_env.afl_testcache_entries) { + + afl->q_testcase_max_cache_entries = + (u32)atoi(afl->afl_env.afl_testcache_entries); + + user_set_cache = 1; + + } + + if (!afl->afl_env.afl_testcache_size || !afl->afl_env.afl_testcache_entries) { + + afl->afl_env.afl_testcache_entries = 0; + afl->afl_env.afl_testcache_size = 0; + + } + if (!afl->q_testcase_max_cache_size) { ACTF( @@ -1347,6 +1363,52 @@ int main(int argc, char **argv_orig, char **envp) { perform_dry_run(afl); + if (!user_set_cache && afl->q_testcase_max_cache_size) { + + /* The user defined not a fixed number of entries for the cache. + Hence we autodetect a good value. After the dry run inputs are + trimmed and we know the average and max size of the input seeds. + We use this information to set a fitting size to max entries + based on the cache size. */ + + struct queue_entry *q = afl->queue; + u64 size = 0, count = 0, avg = 0, max = 0; + + while (q) { + + ++count; + size += q->len; + if (max < q->len) { max = q->len; } + q = q->next; + + } + + if (count) { + + avg = size / count; + avg = ((avg + max) / 2) + 1; + + } + + if (avg < 10240) { avg = 10240; } + + afl->q_testcase_max_cache_entries = afl->q_testcase_max_cache_size / avg; + + if (afl->q_testcase_max_cache_entries > 32768) + afl->q_testcase_max_cache_entries = 32768; + + } + + if (afl->q_testcase_max_cache_entries) { + + OKF("Setting %u maximum entries for the testcase cache", + afl->q_testcase_max_cache_entries); + afl->q_testcase_cache = + ck_alloc(afl->q_testcase_max_cache_entries * sizeof(size_t)); + if (!afl->q_testcase_cache) { PFATAL("malloc failed for cache entries"); } + + } + cull_queue(afl); if (!afl->pending_not_fuzzed) @@ -1366,8 +1428,7 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->not_on_tty) { - sleep(4); - afl->start_time += 4000; + sleep(1); if (afl->stop_soon) { goto stop_fuzzing; } } @@ -1654,6 +1715,7 @@ stop_fuzzing: ck_free(afl->fsrv.target_path); ck_free(afl->fsrv.out_file); ck_free(afl->sync_id); + if (afl->q_testcase_cache) { ck_free(afl->q_testcase_cache); } afl_state_deinit(afl); free(afl); /* not tracked */ -- cgit v1.2.3 From aa0d3785206d52c1815aff850817d55bf50f3598 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 23 Oct 2020 15:21:21 +0200 Subject: better cache entry algo --- src/afl-fuzz-queue.c | 18 +++++++++++++++++ src/afl-fuzz-state.c | 2 +- src/afl-fuzz.c | 55 ++++++++++++++++++++++++++-------------------------- 3 files changed, 47 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index baa80e61..4989a0ba 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -985,6 +985,24 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { /* Cache full. We neet to evict one or more to map one. Get a random one which is not in use */ + if (unlikely(afl->q_testcase_cache_size + len >= afl->q_testcase_max_cache_size && + (afl->q_testcase_cache_count < afl->q_testcase_max_cache_entries && + afl->q_testcase_max_cache_count < + afl->q_testcase_max_cache_entries))) { + + if (afl->q_testcase_max_cache_count > afl->q_testcase_cache_count) { + + afl->q_testcase_max_cache_entries = + afl->q_testcase_max_cache_count + 1; + + } else { + + afl->q_testcase_max_cache_entries = afl->q_testcase_cache_count + 1; + + } + + } + do { // if the cache (MB) is not enough for the queue then this gets diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index ae7d410b..3ce16cad 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -104,7 +104,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->skip_deterministic = 1; afl->use_splicing = 1; afl->q_testcase_max_cache_size = TESTCASE_CACHE_SIZE * 1048576UL; - afl->q_testcase_max_cache_entries = 4096; + afl->q_testcase_max_cache_entries = 64 * 1024; #ifdef HAVE_AFFINITY afl->cpu_aff = -1; /* Selected CPU core */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 637e1985..70e21c0f 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -251,7 +251,7 @@ static int stricmp(char const *a, char const *b) { int main(int argc, char **argv_orig, char **envp) { - s32 opt, i, auto_sync = 0, user_set_cache = 0; + s32 opt, i, auto_sync = 0 /*, user_set_cache = 0*/; u64 prev_queued = 0; u32 sync_interval_cnt = 0, seek_to = 0, show_help = 0, map_size = MAP_SIZE; u8 *extras_dir[4]; @@ -1020,7 +1020,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->q_testcase_max_cache_entries = (u32)atoi(afl->afl_env.afl_testcache_entries); - user_set_cache = 1; + // user_set_cache = 1; } @@ -1363,46 +1363,47 @@ int main(int argc, char **argv_orig, char **envp) { perform_dry_run(afl); - if (!user_set_cache && afl->q_testcase_max_cache_size) { + /* + if (!user_set_cache && afl->q_testcase_max_cache_size) { - /* The user defined not a fixed number of entries for the cache. - Hence we autodetect a good value. After the dry run inputs are - trimmed and we know the average and max size of the input seeds. - We use this information to set a fitting size to max entries - based on the cache size. */ + / * The user defined not a fixed number of entries for the cache. + Hence we autodetect a good value. After the dry run inputs are + trimmed and we know the average and max size of the input seeds. + We use this information to set a fitting size to max entries + based on the cache size. * / - struct queue_entry *q = afl->queue; - u64 size = 0, count = 0, avg = 0, max = 0; + struct queue_entry *q = afl->queue; + u64 size = 0, count = 0, avg = 0, max = 0; - while (q) { + while (q) { - ++count; - size += q->len; - if (max < q->len) { max = q->len; } - q = q->next; + ++count; + size += q->len; + if (max < q->len) { max = q->len; } + q = q->next; - } + } - if (count) { + if (count) { - avg = size / count; - avg = ((avg + max) / 2) + 1; + avg = size / count; + avg = ((avg + max) / 2) + 1; - } + } - if (avg < 10240) { avg = 10240; } + if (avg < 10240) { avg = 10240; } - afl->q_testcase_max_cache_entries = afl->q_testcase_max_cache_size / avg; + afl->q_testcase_max_cache_entries = afl->q_testcase_max_cache_size / avg; - if (afl->q_testcase_max_cache_entries > 32768) - afl->q_testcase_max_cache_entries = 32768; + if (afl->q_testcase_max_cache_entries > 32768) + afl->q_testcase_max_cache_entries = 32768; - } + } + + */ if (afl->q_testcase_max_cache_entries) { - OKF("Setting %u maximum entries for the testcase cache", - afl->q_testcase_max_cache_entries); afl->q_testcase_cache = ck_alloc(afl->q_testcase_max_cache_entries * sizeof(size_t)); if (!afl->q_testcase_cache) { PFATAL("malloc failed for cache entries"); } -- cgit v1.2.3 From 2e8ec1e33943c5067637361a8c182d13412a307c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 23 Oct 2020 22:49:20 +0200 Subject: allow symbolize=1 for asan/debug --- src/afl-fuzz-init.c | 8 ++++++-- src/afl-fuzz.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 13e42e03..1bccff8f 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2338,10 +2338,12 @@ static void handle_resize(int sig) { /* Check ASAN options. */ -void check_asan_opts(void) { +void check_asan_opts(afl_state_t *afl) { u8 *x = get_afl_env("ASAN_OPTIONS"); + (void)(afl); + if (x) { if (!strstr(x, "abort_on_error=1")) { @@ -2350,11 +2352,13 @@ void check_asan_opts(void) { } - if (!strstr(x, "symbolize=0")) { +#ifndef ASAN_BUILD + if (!afl->debug && !strstr(x, "symbolize=0")) { FATAL("Custom ASAN_OPTIONS set without symbolize=0 - please fix!"); } +#endif } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 70e21c0f..22e6d577 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -878,7 +878,7 @@ int main(int argc, char **argv_orig, char **envp) { #endif setup_signal_handlers(); - check_asan_opts(); + check_asan_opts(afl); afl->power_name = power_names[afl->schedule]; -- cgit v1.2.3 From 4e99e3b36c8af6488fde10fac8cdb0797c95e02a Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sat, 24 Oct 2020 03:16:22 +0200 Subject: initializing testcase_buf --- src/afl-fuzz-queue.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 4989a0ba..02e66a4e 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -325,6 +325,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { q->depth = afl->cur_depth + 1; q->passed_det = passed_det; q->trace_mini = NULL; + q->testcase_buf = NULL; if (q->depth > afl->max_depth) { afl->max_depth = q->depth; } -- cgit v1.2.3 From e5f30c690822d69b4d99117024ae2570b1572481 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 24 Oct 2020 16:28:46 +0200 Subject: fix testcache bug --- src/afl-fuzz-init.c | 1 + src/afl-fuzz-queue.c | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 1bccff8f..19a8d77b 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2358,6 +2358,7 @@ void check_asan_opts(afl_state_t *afl) { FATAL("Custom ASAN_OPTIONS set without symbolize=0 - please fix!"); } + #endif } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 02e66a4e..d107dbc8 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -914,20 +914,22 @@ inline void queue_testcase_retake_mem(afl_state_t *afl, struct queue_entry *q, if (likely(q->testcase_buf)) { + u32 is_same = in == q->testcase_buf; + if (likely(len != old_len)) { - afl->q_testcase_cache_size = afl->q_testcase_cache_size + len - old_len; - q->testcase_buf = realloc(q->testcase_buf, len); + u8 *ptr = realloc(q->testcase_buf, len); - if (unlikely(!q->testcase_buf)) { + if (likely(ptr)) { - PFATAL("Unable to malloc '%s' with len %d", q->fname, len); + q->testcase_buf = ptr; + afl->q_testcase_cache_size = afl->q_testcase_cache_size + len - old_len; } } - memcpy(q->testcase_buf, in, len); + if (unlikely(!is_same)) { memcpy(q->testcase_buf, in, len); } } @@ -986,10 +988,12 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { /* Cache full. We neet to evict one or more to map one. Get a random one which is not in use */ - if (unlikely(afl->q_testcase_cache_size + len >= afl->q_testcase_max_cache_size && - (afl->q_testcase_cache_count < afl->q_testcase_max_cache_entries && - afl->q_testcase_max_cache_count < - afl->q_testcase_max_cache_entries))) { + if (unlikely(afl->q_testcase_cache_size + len >= + afl->q_testcase_max_cache_size && + (afl->q_testcase_cache_count < + afl->q_testcase_max_cache_entries && + afl->q_testcase_max_cache_count < + afl->q_testcase_max_cache_entries))) { if (afl->q_testcase_max_cache_count > afl->q_testcase_cache_count) { -- cgit v1.2.3 From ca938e7c4e0c2829625a505732f14410b6299290 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 24 Oct 2020 19:11:41 +0200 Subject: asan_build for tmin and analyze --- src/afl-analyze.c | 5 ++++- src/afl-tmin.c | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-analyze.c b/src/afl-analyze.c index bfdd66e9..0d9ed423 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -743,12 +743,15 @@ static void set_up_environment(void) { } - if (!strstr(x, "symbolize=0")) { +#fndef ASAN_BUILD + if (!getenv("AFL_DEBUG") && !strstr(x, "symbolize=0")) { FATAL("Custom ASAN_OPTIONS set without symbolize=0 - please fix!"); } +#endif + } x = get_afl_env("MSAN_OPTIONS"); diff --git a/src/afl-tmin.c b/src/afl-tmin.c index e1d08054..efc12d4f 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -672,12 +672,15 @@ static void set_up_environment(afl_forkserver_t *fsrv) { } - if (!strstr(x, "symbolize=0")) { +#ifndef ASAN_BUILD + if (!getenv("AFL_DEBUG") && !strstr(x, "symbolize=0")) { FATAL("Custom ASAN_OPTIONS set without symbolize=0 - please fix!"); } +#endif + } x = get_afl_env("MSAN_OPTIONS"); -- cgit v1.2.3 From 029d44a6eca8d11a4c545cfc46accedd63ccb8f2 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 24 Oct 2020 19:20:27 +0200 Subject: asan_build for tmin and analyze --- src/afl-analyze.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 0d9ed423..c8acebb3 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -743,7 +743,7 @@ static void set_up_environment(void) { } -#fndef ASAN_BUILD +#ifndef ASAN_BUILD if (!getenv("AFL_DEBUG") && !strstr(x, "symbolize=0")) { FATAL("Custom ASAN_OPTIONS set without symbolize=0 - please fix!"); -- cgit v1.2.3 From 44c65fa0a0eb0a0382d8b80fa0c8fd3bf25b687d Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 26 Oct 2020 14:44:05 +0100 Subject: add no splicing compile option and print used compile options in afl-fuzz help --- src/afl-fuzz-state.c | 2 ++ src/afl-fuzz.c | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 3ce16cad..61bd06b7 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -102,7 +102,9 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->stats_update_freq = 1; afl->stats_avg_exec = -1; afl->skip_deterministic = 1; +#ifndef NO_SPLICING afl->use_splicing = 1; +#endif afl->q_testcase_max_cache_size = TESTCASE_CACHE_SIZE * 1048576UL; afl->q_testcase_max_cache_entries = 64 * 1024; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 22e6d577..cad26841 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -224,6 +224,26 @@ static void usage(u8 *argv0, int more_help) { SAYF("Compiled without python module support\n"); #endif +#ifdef ASAN_BUILD + SAYF("Compiled with ASAN_BUILD\n\n"); +#endif + +#ifdef NO_SPLICING + SAYF("Compiled with NO_SPLICING\n\n"); +#endif + +#ifdef PROFILING + SAYF("Compiled with PROFILING\n\n"); +#endif + +#ifdef _DEBUG + SAYF("Compiled with _DEBUG\n\n"); +#endif + +#ifdef _AFL_DOCUMENT_MUTATIONS + SAYF("Compiled with _AFL_DOCUMENT_MUTATIONS\n\n"); +#endif + SAYF("For additional help please consult %s/README.md\n\n", doc_path); exit(1); @@ -1527,7 +1547,11 @@ int main(int argc, char **argv_orig, char **envp) { } else { + #ifndef NO_SPLICING afl->use_splicing = 1; + #else + afl->use_splicing = 0; + #endif } -- cgit v1.2.3 From 868cb61ea6a2949e80e8a94fe7b19229bebecd10 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 26 Oct 2020 15:24:33 +0100 Subject: hopeful the final testcache improvement ... --- src/afl-fuzz-queue.c | 56 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index d107dbc8..c78df8be 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -979,21 +979,23 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { if (unlikely(!q->testcase_buf)) { /* Buf not cached, let's load it */ - u32 tid = afl->q_testcase_max_cache_count; + u32 tid = afl->q_testcase_max_cache_count; + static u32 do_once = 0; // because even threaded we would want this. WIP while (unlikely( afl->q_testcase_cache_size + len >= afl->q_testcase_max_cache_size || afl->q_testcase_cache_count >= afl->q_testcase_max_cache_entries - 1)) { - /* Cache full. We neet to evict one or more to map one. - Get a random one which is not in use */ + /* We want a max number of entries to the cache that we learn. + Very simple: once the cache is filled by size - that is the max. */ if (unlikely(afl->q_testcase_cache_size + len >= afl->q_testcase_max_cache_size && (afl->q_testcase_cache_count < afl->q_testcase_max_cache_entries && afl->q_testcase_max_cache_count < - afl->q_testcase_max_cache_entries))) { + afl->q_testcase_max_cache_entries) && + !do_once)) { if (afl->q_testcase_max_cache_count > afl->q_testcase_cache_count) { @@ -1006,8 +1008,19 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { } + do_once = 1; + // release unneeded memory + u8 *ptr = ck_realloc( + afl->q_testcase_cache, + (afl->q_testcase_max_cache_entries + 1) * sizeof(size_t)); + + if (ptr) { afl->q_testcase_cache = (struct queue_entry **)ptr; } + } + /* Cache full. We neet to evict one or more to map one. + Get a random one which is not in use */ + do { // if the cache (MB) is not enough for the queue then this gets @@ -1065,11 +1078,16 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { afl->q_testcase_cache[tid] = q; afl->q_testcase_cache_size += len; ++afl->q_testcase_cache_count; - if (tid >= afl->q_testcase_max_cache_count) + if (likely(tid >= afl->q_testcase_max_cache_count)) { + afl->q_testcase_max_cache_count = tid + 1; - if (tid == afl->q_testcase_smallest_free) + + } else if (unlikely(tid == afl->q_testcase_smallest_free)) { + afl->q_testcase_smallest_free = tid + 1; + } + } return q->testcase_buf; @@ -1093,9 +1111,21 @@ inline void queue_testcase_store_mem(afl_state_t *afl, struct queue_entry *q, } - u32 tid = 0; + u32 tid; + + if (unlikely(afl->q_testcase_max_cache_count >= + afl->q_testcase_max_cache_entries)) { - while (likely(afl->q_testcase_cache[tid] != NULL)) + // uh we were full, so now we have to search from start + tid = afl->q_testcase_smallest_free; + + } else { + + tid = afl->q_testcase_max_cache_count; + + } + + while (unlikely(afl->q_testcase_cache[tid] != NULL)) ++tid; /* Map the test case into memory. */ @@ -1114,8 +1144,16 @@ inline void queue_testcase_store_mem(afl_state_t *afl, struct queue_entry *q, afl->q_testcase_cache[tid] = q; afl->q_testcase_cache_size += len; ++afl->q_testcase_cache_count; - if (tid >= afl->q_testcase_max_cache_count) + + if (likely(tid >= afl->q_testcase_max_cache_count)) { + afl->q_testcase_max_cache_count = tid + 1; + } else if (unlikely(tid == afl->q_testcase_smallest_free)) { + + afl->q_testcase_smallest_free = tid + 1; + + } + } -- cgit v1.2.3 From 0b9b4adbd3955102902823d8f07f4d155d954b8b Mon Sep 17 00:00:00 2001 From: Ruben ten Hove Date: Wed, 28 Oct 2020 14:03:01 +0100 Subject: show supplied -t option so we know it's used --- src/afl-fuzz-stats.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index bec90519..b4b2f747 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -1152,6 +1152,10 @@ void show_init_stats(afl_state_t *afl) { ACTF("Applying timeout settings from resumed session (%u ms).", afl->fsrv.exec_tmout); + } else { + + OKF("-t option specified. We'll use an exec timeout of %s ms.", fsrv->exec_tmout); + } /* In non-instrumented mode, re-running every timing out test case with a -- cgit v1.2.3 From fe705bb9567341427ce1ea39d5fc6b19fdee1646 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Wed, 28 Oct 2020 14:32:53 +0100 Subject: expand havoc if not new findings in the last 5 seconds --- src/afl-fuzz-one.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index bf568c38..2e186b90 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1884,16 +1884,22 @@ havoc_stage: u32 r_max, r; + r_max = 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0); + if (unlikely(afl->expand_havoc)) { /* add expensive havoc cases here, they are activated after a full cycle without finds happened */ - r_max = 16 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0); + r_max += 1; - } else { + } + + if (unlikely(get_cur_time() - afl->last_path_time > 5000)) { + + /* add expensive havoc cases here if there is no findings in the last 5s */ - r_max = 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0); + r_max += 1; } -- cgit v1.2.3 From 587f66f1b341e9ad42655bc74843a2ed1d93ee09 Mon Sep 17 00:00:00 2001 From: Ruben ten Hove Date: Wed, 28 Oct 2020 15:42:07 +0100 Subject: whoops.. --- src/afl-fuzz-stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index b4b2f747..6841eb88 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -1154,7 +1154,7 @@ void show_init_stats(afl_state_t *afl) { } else { - OKF("-t option specified. We'll use an exec timeout of %s ms.", fsrv->exec_tmout); + OKF("-t option specified. We'll use an exec timeout of %s ms.", afl->fsrv.exec_tmout); } -- cgit v1.2.3 From b5686eb63e1fcd6dac49cc458c50e52b51709f8c Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 29 Oct 2020 00:05:28 +0100 Subject: fixes two huge bugs --- src/afl-fuzz-one.c | 5 +++-- src/afl-fuzz-run.c | 3 ++- src/afl-fuzz-stats.c | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 35ff5466..0f3393d2 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1850,8 +1850,9 @@ havoc_stage: r_max += 1; } - - if (unlikely(get_cur_time() - afl->last_path_time > 5000)) { + + if (unlikely(get_cur_time() - afl->last_path_time > 5000 && + afl->ready_for_splicing_count > 1)) { /* add expensive havoc cases here if there is no findings in the last 5s */ diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index dfd3abfb..fb259b5d 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -587,9 +587,10 @@ void sync_fuzzers(afl_state_t *afl) { u8 entry[12]; sprintf(entry, "id:%06u", next_min_accept); + while (m < n) { - if (memcmp(namelist[m]->d_name, entry, 9)) { + if (strcmp(namelist[m]->d_name, entry)) { m++; diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 6841eb88..321bbb35 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -1154,7 +1154,8 @@ void show_init_stats(afl_state_t *afl) { } else { - OKF("-t option specified. We'll use an exec timeout of %s ms.", afl->fsrv.exec_tmout); + ACTF("-t option specified. We'll use an exec timeout of %d ms.", + afl->fsrv.exec_tmout); } -- cgit v1.2.3 From abac876b3aa20d381319d73cbb6c7ad1e7f2395c Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 29 Oct 2020 10:45:32 +0100 Subject: better warn if skipping large dict --- src/afl-fuzz-extras.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 58ce5b6f..88a4fe67 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -451,8 +451,8 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { if (len > MAX_DICT_FILE) { - WARNF("Extra '%.*s' is too big (%s, limit is %s)", (int)len, mem, - stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len), + WARNF("Extra '%.*s' is too big (%s, limit is %s), skipping file!", (int)len, + mem, stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len), stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE)); return; -- cgit v1.2.3 From 9347ad49b8adb867c9829c6c03e574ce26bc0942 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 29 Oct 2020 11:05:07 +0100 Subject: Don't crash for unset out_file (fixed #562) --- src/afl-forkserver.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index df300950..04195d00 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -968,7 +968,7 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { s32 fd = fsrv->out_fd; - if (!fsrv->use_stdin) { + if (!fsrv->use_stdin && fsrv->out_file) { if (fsrv->no_unlink) { @@ -983,6 +983,11 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { if (fd < 0) { PFATAL("Unable to create '%s'", fsrv->out_file); } + } else if (unlikely(!fd)) { + + // We should never have stdin as fd here, 0 is likely unset. + FATAL("Nowhere to write output to (neither out_fd nor out_file set)"); + } else { lseek(fd, 0, SEEK_SET); -- cgit v1.2.3 From a2739ef5ff2cbb16d23d3d9c0ee1b13b892c1f72 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 30 Oct 2020 09:40:51 +0100 Subject: extras: afl_realloc -> ck_realloc --- src/afl-forkserver.c | 2 +- src/afl-fuzz-extras.c | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 04195d00..d23cf6eb 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -984,7 +984,7 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { if (fd < 0) { PFATAL("Unable to create '%s'", fsrv->out_file); } } else if (unlikely(!fd)) { - + // We should never have stdin as fd here, 0 is likely unset. FATAL("Nowhere to write output to (neither out_fd nor out_file set)"); diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 88a4fe67..4fb48860 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -423,8 +423,8 @@ void dedup_extras(afl_state_t *afl) { } if (afl->extras_cnt != orig_cnt) - afl->extras = afl_realloc((void **)&afl->extras, - afl->extras_cnt * sizeof(struct extra_data)); + afl->extras = ck_realloc((void **)&afl->extras, + afl->extras_cnt * sizeof(struct extra_data)); } @@ -462,8 +462,18 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { } - afl->extras = afl_realloc((void **)&afl->extras, - (afl->extras_cnt + 1) * sizeof(struct extra_data)); + if (afl->extra) { + + afl->extras = ck_realloc((void **)&afl->extras, + (afl->extras_cnt + 1) * sizeof(struct extra_data)); + + } else { + + afl->extras = ck_alloc((void **)&afl->extras, + (afl->extras_cnt + 1) * sizeof(struct extra_data)); + + } + if (unlikely(!afl->extras)) { PFATAL("alloc"); } afl->extras[afl->extras_cnt].data = ck_alloc(len); -- cgit v1.2.3 From b33306ca2cb823e40769dda733542063dce0658f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 30 Oct 2020 09:43:03 +0100 Subject: fix ck_alloc call --- src/afl-fuzz-extras.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 4fb48860..5beceac9 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -469,8 +469,7 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { } else { - afl->extras = ck_alloc((void **)&afl->extras, - (afl->extras_cnt + 1) * sizeof(struct extra_data)); + afl->extras = ck_alloc((afl->extras_cnt + 1) * sizeof(struct extra_data)); } -- cgit v1.2.3 From e0bdfd87b62ea7f30d9ae7fa4a838004a3983f83 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 30 Oct 2020 09:44:06 +0100 Subject: fix ck_alloc call --- src/afl-fuzz-extras.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 5beceac9..adec986e 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -462,7 +462,7 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { } - if (afl->extra) { + if (afl->extras) { afl->extras = ck_realloc((void **)&afl->extras, (afl->extras_cnt + 1) * sizeof(struct extra_data)); -- cgit v1.2.3 From f810639ab188bf3bbd27fe58fb0b0bb2fe4fbdf0 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 31 Oct 2020 14:18:58 +0100 Subject: add our own inline trace-pc-guard --- src/afl-cc.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index c516dc4c..1a7a837f 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -501,11 +501,22 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (instrument_mode == INSTRUMENT_PCGUARD) { -#if LLVM_MAJOR >= 4 +#if LLVM_MAJOR >= 10 + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = - "-fsanitize-coverage=trace-pc-guard"; // edge coverage by default + alloc_printf("%s/SanitizerCoveragePCGUARD.so", obj_path); #else + #if LLVM_MAJOR >= 4 + if (!be_quiet) + SAYF( + "Using unoptimized trace-pc-guard, upgrade to llvm 10+ for " + "enhanced version.\n"); + cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; + #else FATAL("pcguard instrumentation requires llvm 4.0.1+"); + #endif #endif } else { -- cgit v1.2.3 From 20a8a93fd193f7526f5e3d0cd1dfa43df9d2c4f6 Mon Sep 17 00:00:00 2001 From: Rumata888 Date: Thu, 12 Nov 2020 01:13:57 +0300 Subject: Fixed symcc custom mutator --- src/afl-fuzz-bitmap.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 735420c3..4b29672a 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -584,7 +584,10 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_paths); #endif /* ^!SIMPLE_FILES */ - + fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, 0600); + if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", queue_fn); } + ck_write(fd, mem, len, queue_fn); + close(fd); add_to_queue(afl, queue_fn, len, 0); #ifdef INTROSPECTION @@ -623,11 +626,6 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { } - fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, 0600); - if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", queue_fn); } - ck_write(fd, mem, len, queue_fn); - close(fd); - if (likely(afl->q_testcase_max_cache_size)) { queue_testcase_store_mem(afl, afl->queue_top, mem); -- cgit v1.2.3 From bd313d4039d094c0caf657b4ed1a666da7eded1b Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 14 Nov 2020 11:31:18 +0100 Subject: no binary checking in noninstrumented mode --- src/afl-fuzz.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 269ce1bf..59772b3f 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1338,11 +1338,11 @@ int main(int argc, char **argv_orig, char **envp) { } - if (!afl->fsrv.qemu_mode) { check_binary(afl, afl->cmplog_binary); } + if (!afl->fsrv.qemu_mode && !afl->non_instrumented_mode) { check_binary(afl, afl->cmplog_binary); } } - check_binary(afl, argv[optind]); + if (afl->non_instrumented_mode) check_binary(afl, argv[optind]); if (afl->shmem_testcase_mode) { setup_testcase_shmem(afl); } -- cgit v1.2.3 From 30cd8a8397419b3eedb6ee939e290b4c6b8c2cf1 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 14 Nov 2020 12:28:51 +0100 Subject: fix non instrumented mode, fix check_binary --- src/afl-fuzz-init.c | 6 ------ src/afl-fuzz.c | 10 +++++++++- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 19a8d77b..01929a0a 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2300,12 +2300,6 @@ void fix_up_sync(afl_state_t *afl) { u8 *x = afl->sync_id; - if (afl->non_instrumented_mode) { - - FATAL("-S / -M and -n are mutually exclusive"); - - } - while (*x) { if (!isalnum(*x) && *x != '_' && *x != '-') { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 59772b3f..f662b308 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -435,6 +435,7 @@ int main(int argc, char **argv_orig, char **envp) { u8 *c; + if (afl->non_instrumented_mode) { FATAL("-M is not supported in non-instrumented mode "); } if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); } afl->sync_id = ck_strdup(optarg); afl->skip_deterministic = 0; // force determinsitic fuzzing @@ -464,6 +465,7 @@ int main(int argc, char **argv_orig, char **envp) { case 'S': /* secondary sync id */ + if (afl->non_instrumented_mode) { FATAL("-S is not supported in non-instrumented mode "); } if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); } afl->sync_id = ck_strdup(optarg); afl->is_secondary_node = 1; @@ -620,6 +622,12 @@ int main(int argc, char **argv_orig, char **envp) { case 'n': /* dumb mode */ + if (afl->is_main_node || afl->is_secondary_node) { + + FATAL("Non instrumented mode is not supported with -M / -S"); + + } + if (afl->non_instrumented_mode) { FATAL("Multiple -n options not supported"); @@ -1342,7 +1350,7 @@ int main(int argc, char **argv_orig, char **envp) { } - if (afl->non_instrumented_mode) check_binary(afl, argv[optind]); + if (!afl->non_instrumented_mode) check_binary(afl, argv[optind]); if (afl->shmem_testcase_mode) { setup_testcase_shmem(afl); } -- cgit v1.2.3 From e750a5c856486bb89401f3555ca529bf743146f4 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 14 Nov 2020 12:36:28 +0100 Subject: add sanity check for -M/-S arguments --- src/afl-fuzz.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index f662b308..6b19d648 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -435,8 +435,12 @@ int main(int argc, char **argv_orig, char **envp) { u8 *c; - if (afl->non_instrumented_mode) { FATAL("-M is not supported in non-instrumented mode "); } + if (afl->non_instrumented_mode) { FATAL("-M is not supported in non-instrumented mode"); } if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); } + + /* sanity check for argument: should not begin with '-' (possible option) */ + if (optarg && *optarg == '-') { FATAL("argument for -M started with a dash '-', which is used for options"); } + afl->sync_id = ck_strdup(optarg); afl->skip_deterministic = 0; // force determinsitic fuzzing afl->old_seed_selection = 1; // force old queue walking seed selection @@ -465,8 +469,12 @@ int main(int argc, char **argv_orig, char **envp) { case 'S': /* secondary sync id */ - if (afl->non_instrumented_mode) { FATAL("-S is not supported in non-instrumented mode "); } + if (afl->non_instrumented_mode) { FATAL("-S is not supported in non-instrumented mode"); } if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); } + + /* sanity check for argument: should not begin with '-' (possible option) */ + if (optarg && *optarg == '-') { FATAL("argument for -M started with a dash '-', which is used for options"); } + afl->sync_id = ck_strdup(optarg); afl->is_secondary_node = 1; break; -- cgit v1.2.3 From 40e10895a2b7b69425ee03b2ec6e478184120ee2 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 14 Nov 2020 17:21:43 +0100 Subject: now really fix -n --- src/afl-forkserver.c | 25 +++++++++++++++++-------- src/afl-fuzz-init.c | 2 +- src/afl-fuzz.c | 2 +- 3 files changed, 19 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 45be2abd..266f021b 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -116,7 +116,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->use_fauxsrv = 0; fsrv_to->last_run_timed_out = 0; - fsrv_to->init_child_func = fsrv_exec_child; + fsrv_to->init_child_func = from->init_child_func; // Note: do not copy ->add_extra_func list_append(&fsrv_list, fsrv_to); @@ -220,7 +220,15 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) { } void (*old_sigchld_handler)(int) = signal(SIGCHLD, SIG_DFL); - +#if 0 + WARNF("targetpath=%s", fsrv->target_path); + if (argv) { + for (char *p = argv[0]; p; ++p) { + WARNF(" %s", p); + } + } + WARNF("\n"); +#endif while (1) { uint32_t was_killed; @@ -272,7 +280,8 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) { *(u32 *)fsrv->trace_bits = EXEC_FAIL_SIG; - PFATAL("Execv failed in fauxserver."); + WARNF("Execv failed in fauxserver."); + break; } @@ -286,13 +295,13 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) { if (waitpid(child_pid, &status, 0) < 0) { // Zombie Child could not be collected. Scary! - PFATAL("Fauxserver could not determin child's exit code. "); + WARNF("Fauxserver could not determine child's exit code. "); } /* Relay wait status to AFL pipe, then loop back. */ - if (write(FORKSRV_FD + 1, &status, 4) != 4) { exit(0); } + if (write(FORKSRV_FD + 1, &status, 4) != 4) { exit(1); } } @@ -330,7 +339,7 @@ static void report_error_and_exit(int error) { "memory failed."); break; default: - FATAL("unknown error code %u from fuzzing target!", error); + FATAL("unknown error code %d from fuzzing target!", error); } @@ -355,7 +364,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (fsrv->use_fauxsrv) { - /* TODO: Come up with sone nice way to initialize this all */ + /* TODO: Come up with some nice way to initialize this all */ if (fsrv->init_child_func != fsrv_exec_child) { @@ -520,7 +529,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, *(u32 *)fsrv->trace_bits = EXEC_FAIL_SIG; fprintf(stderr, "Error: execv to target failed\n"); - exit(0); + exit(1); } diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 01929a0a..8b9b0a6f 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2497,7 +2497,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { } - if (afl->afl_env.afl_skip_bin_check || afl->use_wine || afl->unicorn_mode) { + if (afl->afl_env.afl_skip_bin_check || afl->use_wine || afl->unicorn_mode || afl->non_instrumented_mode) { return; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 6b19d648..39af1e18 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1358,7 +1358,7 @@ int main(int argc, char **argv_orig, char **envp) { } - if (!afl->non_instrumented_mode) check_binary(afl, argv[optind]); + check_binary(afl, argv[optind]); if (afl->shmem_testcase_mode) { setup_testcase_shmem(afl); } -- cgit v1.2.3 From 76c5b8a3b420bfb74191cf4d3e44b067a268dc7f Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 14 Nov 2020 19:38:06 +0100 Subject: fix error handling in fauxserver --- src/afl-forkserver.c | 12 ++---------- src/afl-fuzz.c | 4 ++-- 2 files changed, 4 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 266f021b..3814a77e 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -220,15 +220,7 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) { } void (*old_sigchld_handler)(int) = signal(SIGCHLD, SIG_DFL); -#if 0 - WARNF("targetpath=%s", fsrv->target_path); - if (argv) { - for (char *p = argv[0]; p; ++p) { - WARNF(" %s", p); - } - } - WARNF("\n"); -#endif + while (1) { uint32_t was_killed; @@ -1146,7 +1138,7 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, } // Fauxserver should handle this now. - // if (tb4 == EXEC_FAIL_SIG) return FSRV_RUN_ERROR; + if (*(u32 *)fsrv->trace_bits == EXEC_FAIL_SIG) return FSRV_RUN_ERROR; return FSRV_RUN_OK; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 39af1e18..c1ddd413 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -442,7 +442,7 @@ int main(int argc, char **argv_orig, char **envp) { if (optarg && *optarg == '-') { FATAL("argument for -M started with a dash '-', which is used for options"); } afl->sync_id = ck_strdup(optarg); - afl->skip_deterministic = 0; // force determinsitic fuzzing + afl->skip_deterministic = 0; // force deterministic fuzzing afl->old_seed_selection = 1; // force old queue walking seed selection if ((c = strchr(afl->sync_id, ':'))) { @@ -922,7 +922,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->power_name = power_names[afl->schedule]; - if (!afl->sync_id) { + if (!afl->non_instrumented_mode && !afl->sync_id) { auto_sync = 1; afl->sync_id = ck_strdup("default"); -- cgit v1.2.3 From ea689076b330c46223ed1c36f9b02fc319c798f8 Mon Sep 17 00:00:00 2001 From: Dustin Spicuzza Date: Sat, 14 Nov 2020 19:54:51 -0500 Subject: Actually make python 'fuzz' method optional At some point mutator->afl_custom_fuzz was allowed to be NULL, so do that instead of crashing --- src/afl-fuzz-python.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 596b733e..cfaf055d 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -329,9 +329,7 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, if (py_functions[PY_FUNC_DEINIT]) { mutator->afl_custom_deinit = deinit_py; } - /* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator - is quite different from the custom mutator. */ - mutator->afl_custom_fuzz = fuzz_py; + if (py_functions[PY_FUNC_FUZZ]) { mutator->afl_custom_fuzz = fuzz_py; } if (py_functions[PY_FUNC_POST_PROCESS]) { -- cgit v1.2.3 From 1cc637a0a05a043a223f69fb9661ecc3d5597d23 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 16 Nov 2020 10:59:09 +0100 Subject: support AFL_LLVM_INSTRUMENT env for our own PCGUARD --- src/afl-cc.c | 113 +++++++++++++++++++++++++++++----------------------- src/afl-fuzz-init.c | 3 +- src/afl-fuzz.c | 42 +++++++++++++++---- 3 files changed, 101 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 771a58f5..5d8d33a5 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -49,14 +49,14 @@ static u8 * obj_path; /* Path to runtime libraries */ static u8 **cc_params; /* Parameters passed to the real CC */ static u32 cc_par_cnt = 1; /* Param count, including argv0 */ static u8 llvm_fullpath[PATH_MAX]; -static u8 instrument_mode, instrument_opt_mode, ngram_size, lto_mode, - compiler_mode, plusplus_mode; -static u8 have_gcc, have_llvm, have_gcc_plugin, have_lto; -static u8 *lto_flag = AFL_CLANG_FLTO, *argvnull; -static u8 debug; -static u8 cwd[4096]; -static u8 cmplog_mode; -u8 use_stdin; /* dummy */ +static u8 instrument_mode, instrument_opt_mode, ngram_size, lto_mode; +static u8 compiler_mode, plusplus_mode, have_instr_env = 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; +static u8 cwd[4096]; +static u8 cmplog_mode; +u8 use_stdin; /* dummy */ // static u8 *march_opt = CFLAGS_OPT; enum { @@ -354,19 +354,13 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (lto_mode && plusplus_mode) cc_params[cc_par_cnt++] = "-lc++"; // needed by fuzzbench, early - if (lto_mode) { - - if (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || - getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") || - getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) { + if (lto_mode && have_instr_env) { - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = "-load"; - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = - alloc_printf("%s/afl-llvm-lto-instrumentlist.so", obj_path); - - } + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-lto-instrumentlist.so", obj_path); } @@ -508,11 +502,25 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (instrument_mode == INSTRUMENT_PCGUARD) { #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = "-load"; - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = - alloc_printf("%s/SanitizerCoveragePCGUARD.so", obj_path); + if (have_instr_list) { + + if (!be_quiet) + SAYF( + "Using unoptimized trace-pc-guard, due usage of " + "-fsanitize-coverage-allow/denylist, you can use " + "AFL_LLVM_ALLOWLIST/AFL_LLMV_DENYLIST instead.\n"); + cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; + + } else { + + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/SanitizerCoveragePCGUARD.so", obj_path); + + } + #else #if LLVM_MAJOR >= 4 if (!be_quiet) @@ -590,6 +598,9 @@ 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; @@ -856,6 +867,14 @@ int main(int argc, char **argv, char **envp) { be_quiet = 1; + if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST") || + getenv("AFL_LLVM_ALLOWLIST") || getenv("AFL_LLVM_DENYLIST") || + getenv("AFL_LLVM_BLOCKLIST")) { + + have_instr_env = 1; + + } + if ((ptr = strrchr(callname, '/')) != NULL) callname = ptr + 1; argvnull = (u8 *)argv[0]; check_environment_vars(envp); @@ -1015,14 +1034,14 @@ int main(int argc, char **argv, char **envp) { } - if ((getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || - getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") || - getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) && - getenv("AFL_DONT_OPTIMIZE")) + if (have_instr_env && getenv("AFL_DONT_OPTIMIZE")) { + WARNF( "AFL_LLVM_ALLOWLIST/DENYLIST and AFL_DONT_OPTIMIZE cannot be combined " "for file matching, only function matching!"); + } + if (getenv("AFL_LLVM_INSTRIM") || getenv("INSTRIM") || getenv("INSTRIM_LIB")) { @@ -1426,22 +1445,20 @@ int main(int argc, char **argv, char **envp) { #if LLVM_MAJOR <= 6 instrument_mode = INSTRUMENT_AFL; #else - if (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || - getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") || - getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) { + #if LLVM_MAJOR < 11 && (LLVM_MAJOR < 10 || LLVM_MINOR < 1) + if (have_instr_env) { instrument_mode = INSTRUMENT_AFL; - WARNF( - "switching to classic instrumentation because " - "AFL_LLVM_ALLOWLIST/DENYLIST does not work with PCGUARD. Use " - "-fsanitize-coverage-allowlist=allowlist.txt or " - "-fsanitize-coverage-blocklist=denylist.txt if you want to use " - "PCGUARD. Requires llvm 12+. See https://clang.llvm.org/docs/ " - "SanitizerCoverage.html#partially-disabling-instrumentation"); + if (!be_quiet) + WARNF( + "Switching to classic instrumentation because " + "AFL_LLVM_ALLOWLIST/DENYLIST does not work with PCGUARD < 10.0.1."); } else + #endif instrument_mode = INSTRUMENT_PCGUARD; + #endif } @@ -1487,18 +1504,16 @@ int main(int argc, char **argv, char **envp) { "AFL_LLVM_NOT_ZERO and AFL_LLVM_SKIP_NEVERZERO can not be set " "together"); - if (instrument_mode == INSTRUMENT_PCGUARD && - (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL || - getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") || - getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST"))) +#if LLVM_MAJOR < 11 && (LLVM_MAJOR < 10 || LLVM_MINOR < 1) + if (instrument_mode == INSTRUMENT_PCGUARD && have_instr_env) { + FATAL( "Instrumentation type PCGUARD does not support " - "AFL_LLVM_ALLOWLIST/DENYLIST! Use " - "-fsanitize-coverage-allowlist=allowlist.txt or " - "-fsanitize-coverage-blocklist=denylist.txt instead (requires llvm " - "12+), see " - "https://clang.llvm.org/docs/" - "SanitizerCoverage.html#partially-disabling-instrumentation"); + "AFL_LLVM_ALLOWLIST/DENYLIST! Use LLVM 10.0.1+ instead."); + + } + +#endif u8 *ptr2; diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 8b9b0a6f..6884bb1d 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2497,7 +2497,8 @@ void check_binary(afl_state_t *afl, u8 *fname) { } - if (afl->afl_env.afl_skip_bin_check || afl->use_wine || afl->unicorn_mode || afl->non_instrumented_mode) { + if (afl->afl_env.afl_skip_bin_check || afl->use_wine || afl->unicorn_mode || + afl->non_instrumented_mode) { return; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index c1ddd413..cedfdf8f 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -435,11 +435,23 @@ int main(int argc, char **argv_orig, char **envp) { u8 *c; - if (afl->non_instrumented_mode) { FATAL("-M is not supported in non-instrumented mode"); } + if (afl->non_instrumented_mode) { + + FATAL("-M is not supported in non-instrumented mode"); + + } + if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); } - /* sanity check for argument: should not begin with '-' (possible option) */ - if (optarg && *optarg == '-') { FATAL("argument for -M started with a dash '-', which is used for options"); } + /* sanity check for argument: should not begin with '-' (possible + * option) */ + if (optarg && *optarg == '-') { + + FATAL( + "argument for -M started with a dash '-', which is used for " + "options"); + + } afl->sync_id = ck_strdup(optarg); afl->skip_deterministic = 0; // force deterministic fuzzing @@ -469,11 +481,23 @@ int main(int argc, char **argv_orig, char **envp) { case 'S': /* secondary sync id */ - if (afl->non_instrumented_mode) { FATAL("-S is not supported in non-instrumented mode"); } + if (afl->non_instrumented_mode) { + + FATAL("-S is not supported in non-instrumented mode"); + + } + if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); } - /* sanity check for argument: should not begin with '-' (possible option) */ - if (optarg && *optarg == '-') { FATAL("argument for -M started with a dash '-', which is used for options"); } + /* sanity check for argument: should not begin with '-' (possible + * option) */ + if (optarg && *optarg == '-') { + + FATAL( + "argument for -M started with a dash '-', which is used for " + "options"); + + } afl->sync_id = ck_strdup(optarg); afl->is_secondary_node = 1; @@ -1354,7 +1378,11 @@ int main(int argc, char **argv_orig, char **envp) { } - if (!afl->fsrv.qemu_mode && !afl->non_instrumented_mode) { check_binary(afl, afl->cmplog_binary); } + if (!afl->fsrv.qemu_mode && !afl->non_instrumented_mode) { + + check_binary(afl, afl->cmplog_binary); + + } } -- cgit v1.2.3 From c06b5a156480d70e5013a780bb41bd074637475c Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 17 Nov 2020 17:02:33 +0100 Subject: fix sync issue --- src/afl-fuzz-run.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index e969994d..b96fe71a 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -590,7 +590,7 @@ void sync_fuzzers(afl_state_t *afl) { while (m < n) { - if (strcmp(namelist[m]->d_name, entry)) { + if (strncmp(namelist[m]->d_name, entry, 9)) { m++; -- cgit v1.2.3 From 54fdec0e51d17ac47582ca23c32ce10da5591aa2 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 17 Nov 2020 21:07:29 +0100 Subject: fix: avoid preprocessor logic in macro arguments (not portable) --- src/afl-cc.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 5d8d33a5..ef4d2c74 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1326,15 +1326,18 @@ int main(int argc, char **argv, char **envp) { " AFL_GCC_INSTRUMENT_FILE: enable selective instrumentation by " "filename\n"); +#if LLVM_MAJOR < 9 +#define COUNTER_BEHAVIOUR " AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n" +#else +#define COUNTER_BEHAVIOUR " AFL_LLVM_SKIP_NEVERZERO: do not skip zero on trace counters\n" +#endif if (have_llvm) SAYF( "\nLLVM/LTO/afl-clang-fast/afl-clang-lto specific environment " "variables:\n" -#if LLVM_MAJOR < 9 - " AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n" -#else - " AFL_LLVM_SKIP_NEVERZERO: do not skip zero on trace counters\n" -#endif + + COUNTER_BEHAVIOUR + " AFL_LLVM_DICT2FILE: generate an afl dictionary based on found " "comparisons\n" " AFL_LLVM_LAF_ALL: enables all LAF splits/transforms\n" -- cgit v1.2.3 From 23f37ff5054d77abf7baf7b6d01d660b435d81cd Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 18 Nov 2020 02:33:47 +0100 Subject: fixed alloc errors, code format --- src/afl-cc.c | 6 ++++-- src/afl-fuzz-python.c | 6 +++--- src/afl-fuzz-queue.c | 7 ++++++- src/afl-fuzz.c | 2 ++ 4 files changed, 15 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index ef4d2c74..9c23c18b 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1327,9 +1327,11 @@ int main(int argc, char **argv, char **envp) { "filename\n"); #if LLVM_MAJOR < 9 -#define COUNTER_BEHAVIOUR " AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n" + #define COUNTER_BEHAVIOUR \ + " AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n" #else -#define COUNTER_BEHAVIOUR " AFL_LLVM_SKIP_NEVERZERO: do not skip zero on trace counters\n" + #define COUNTER_BEHAVIOUR \ + " AFL_LLVM_SKIP_NEVERZERO: do not skip zero on trace counters\n" #endif if (have_llvm) SAYF( diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index cfaf055d..80532774 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -96,7 +96,7 @@ static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf, mutated_size = PyByteArray_Size(py_value); *out_buf = afl_realloc(BUF_PARAMS(fuzz), mutated_size); - if (unlikely(!out_buf)) { PFATAL("alloc"); } + if (unlikely(!*out_buf)) { PFATAL("alloc"); } memcpy(*out_buf, PyByteArray_AsString(py_value), mutated_size); Py_DECREF(py_value); @@ -579,7 +579,7 @@ size_t trim_py(void *py_mutator, u8 **out_buf) { ret = PyByteArray_Size(py_value); *out_buf = afl_realloc(BUF_PARAMS(trim), ret); - if (unlikely(!out_buf)) { PFATAL("alloc"); } + if (unlikely(!*out_buf)) { PFATAL("alloc"); } memcpy(*out_buf, PyByteArray_AsString(py_value), ret); Py_DECREF(py_value); @@ -645,7 +645,7 @@ size_t havoc_mutation_py(void *py_mutator, u8 *buf, size_t buf_size, /* A new buf is needed... */ *out_buf = afl_realloc(BUF_PARAMS(havoc), mutated_size); - if (unlikely(!out_buf)) { PFATAL("alloc"); } + if (unlikely(!*out_buf)) { PFATAL("alloc"); } } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index c78df8be..32bed06f 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -56,7 +56,12 @@ void create_alias_table(afl_state_t *afl) { int * S = (u32 *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32)); int * L = (u32 *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32)); - if (!P || !S || !L) { FATAL("could not aquire memory for alias table"); } + if (!P || !S || !L || !afl->alias_table || !afl->alias_probability) { + + FATAL("could not aquire memory for alias table"); + + } + memset((void *)afl->alias_table, 0, n * sizeof(u32)); memset((void *)afl->alias_probability, 0, n * sizeof(double)); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index cedfdf8f..ac77bb1f 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -350,6 +350,7 @@ int main(int argc, char **argv_orig, char **envp) { case 's': { + if (optarg == NULL) { FATAL("No valid seed provided. Got NULL."); } rand_set_seed(afl, strtoul(optarg, 0L, 10)); afl->fixed_seed = 1; break; @@ -419,6 +420,7 @@ int main(int argc, char **argv_orig, char **envp) { case 'i': /* input dir */ if (afl->in_dir) { FATAL("Multiple -i options not supported"); } + if (afl->in_dir == NULL) { FATAL("Invalid -i option (got NULL)."); } afl->in_dir = optarg; if (!strcmp(afl->in_dir, "-")) { afl->in_place_resume = 1; } -- cgit v1.2.3 From f80f62f14bb5222344925a7ec51c81aa2f95d86e Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 18 Nov 2020 03:02:13 +0100 Subject: renamed env var to AFL_DEBUG_CHILD --- src/afl-fuzz-run.c | 2 +- src/afl-fuzz-state.c | 6 ++++-- src/afl-fuzz.c | 4 ++-- src/afl-showmap.c | 6 +++++- src/afl-tmin.c | 7 +++++-- 5 files changed, 17 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index b96fe71a..95b3ee8a 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -332,7 +332,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, } afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, - afl->afl_env.afl_debug_child_output); + afl->afl_env.afl_debug_child); if (afl->fsrv.support_shmem_fuzz && !afl->fsrv.use_shmem_fuzz) { diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 61bd06b7..489d4e53 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -268,11 +268,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_bench_until_crash = get_afl_env(afl_environment_variables[i]) ? 1 : 0; - } else if (!strncmp(env, "AFL_DEBUG_CHILD_OUTPUT", + } else if (!strncmp(env, "AFL_DEBUG_CHILD", + afl_environment_variable_len) || + !strncmp(env, "AFL_DEBUG_CHILD_OUTPUT", afl_environment_variable_len)) { - afl->afl_env.afl_debug_child_output = + afl->afl_env.afl_debug_child = get_afl_env(afl_environment_variables[i]) ? 1 : 0; } else if (!strncmp(env, "AFL_AUTORESUME", diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index ac77bb1f..e04ae649 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -166,7 +166,7 @@ static void usage(u8 *argv0, int more_help) { "AFL_CUSTOM_MUTATOR_ONLY: avoid AFL++'s internal mutators\n" "AFL_CYCLE_SCHEDULES: after completing a cycle, switch to a different -p schedule\n" "AFL_DEBUG: extra debugging output for Python mode trimming\n" - "AFL_DEBUG_CHILD_OUTPUT: do not suppress stdout/stderr from target\n" + "AFL_DEBUG_CHILD: do not suppress stdout/stderr from target\n" "AFL_DISABLE_TRIM: disable the trimming of test cases\n" "AFL_DUMB_FORKSRV: use fork server without feedback from target\n" "AFL_EXIT_WHEN_DONE: exit when all inputs are run and no new finds are found\n" @@ -1426,7 +1426,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary; afl->cmplog_fsrv.init_child_func = cmplog_exec_child; afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, - afl->afl_env.afl_debug_child_output); + afl->afl_env.afl_debug_child); OKF("Cmplog forkserver successfully started"); } diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 4b357254..69527007 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1091,7 +1091,11 @@ int main(int argc, char **argv_orig, char **envp) { } afl_fsrv_start(fsrv, use_argv, &stop_soon, - get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0); + (get_afl_env("AFL_DEBUG_CHILD") || + get_afl_env("AFL_DEBUG_CHILD_OUTPUT")) + ? 1 + : 0); + map_size = fsrv->map_size; if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz) diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 06037d61..e4fb068d 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -1141,8 +1141,11 @@ int main(int argc, char **argv_orig, char **envp) { read_initial_file(); - afl_fsrv_start(fsrv, use_argv, &stop_soon, - get_afl_env("AFL_DEBUG_CHILD_OUTPUT") ? 1 : 0); + afl_fsrv_start( + fsrv, use_argv, &stop_soon, + (get_afl_env("AFL_DEBUG_CHILD") || get_afl_env("AFL_DEBUG_CHILD_OUTPUT")) + ? 1 + : 0); if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz); -- cgit v1.2.3 From 631b6d0187ae59409549c431c657def8c30da8cf Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 18 Nov 2020 03:03:49 +0100 Subject: fixed simple yet stupid bug --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e04ae649..1008f28c 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -420,7 +420,7 @@ int main(int argc, char **argv_orig, char **envp) { case 'i': /* input dir */ if (afl->in_dir) { FATAL("Multiple -i options not supported"); } - if (afl->in_dir == NULL) { FATAL("Invalid -i option (got NULL)."); } + if (optarg == NULL) { FATAL("Invalid -i option (got NULL)."); } afl->in_dir = optarg; if (!strcmp(afl->in_dir, "-")) { afl->in_place_resume = 1; } -- cgit v1.2.3 From 108a89b55959ed41fa3b050696148e698e6de2df Mon Sep 17 00:00:00 2001 From: hexcoder Date: Wed, 18 Nov 2020 08:33:06 +0100 Subject: typo --- src/afl-fuzz-queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 32bed06f..f35b4f57 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -58,7 +58,7 @@ void create_alias_table(afl_state_t *afl) { if (!P || !S || !L || !afl->alias_table || !afl->alias_probability) { - FATAL("could not aquire memory for alias table"); + FATAL("could not acquire memory for alias table"); } -- cgit v1.2.3 From b260204b728efcc4ba13dfa77692cfc5721db606 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Wed, 18 Nov 2020 18:13:03 +0000 Subject: Solaris/Illumos build fix. (#609) --- src/afl-cc.c | 2 +- src/afl-fuzz-init.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 9c23c18b..19dc9a6a 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -837,7 +837,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } - #ifndef __APPLE__ + #if !defined(__APPLE__) && !defined(__sun) if (!shared_linking) cc_params[cc_par_cnt++] = alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 6884bb1d..0360cdb0 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -355,7 +355,7 @@ void bind_to_free_cpu(afl_state_t *afl) { if (ncpus > sizeof(cpu_used)) ncpus = sizeof(cpu_used); - for (i = 0; i < ncpus; i++) { + for (i = 0; i < (s32)ncpus; i++) { k = kstat_lookup(m, "cpu_stat", i, NULL); if (kstat_read(m, k, &cs)) { -- cgit v1.2.3 From cd0a25be5e9b05a2ab6a11592cd95e7f653bf42d Mon Sep 17 00:00:00 2001 From: Dustin Spicuzza Date: Wed, 18 Nov 2020 14:29:17 -0500 Subject: Use buffer protocol to retrieve result from python post_process (#605) Saves an extra copy, gives post processing functions more flexibility --- src/afl-fuzz-python.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 80532774..9ac4403b 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -134,6 +134,18 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { PyObject * py_module = py->py_module; PyObject **py_functions = py->py_functions; + // initialize the post process buffer; ensures it's always valid + PyObject *unused_bytes = PyByteArray_FromStringAndSize("OHAI", 4); + if (!unused_bytes) { FATAL("allocation failed!"); } + if (PyObject_GetBuffer(unused_bytes, &py->post_process_buf, PyBUF_SIMPLE) == + -1) { + + FATAL("buffer initialization failed"); + + } + + Py_DECREF(unused_bytes); + if (py_module != NULL) { u8 py_notrim = 0, py_idx; @@ -313,7 +325,6 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, struct custom_mutator *mutator; mutator = ck_alloc(sizeof(struct custom_mutator)); - mutator->post_process_buf = NULL; mutator->name = module_name; ACTF("Loading Python mutator library from '%s'...", module_name); @@ -403,10 +414,13 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, size_t post_process_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) { - size_t py_out_buf_size; PyObject * py_args, *py_value; py_mutator_t *py = (py_mutator_t *)py_mutator; + // buffer returned previously must be released; initialized during init + // so we don't need to do comparisons + PyBuffer_Release(&py->post_process_buf); + py_args = PyTuple_New(1); py_value = PyByteArray_FromStringAndSize(buf, buf_size); if (!py_value) { @@ -426,20 +440,20 @@ size_t post_process_py(void *py_mutator, u8 *buf, size_t buf_size, if (py_value != NULL) { - py_out_buf_size = PyByteArray_Size(py_value); + if (PyObject_GetBuffer(py_value, &py->post_process_buf, PyBUF_SIMPLE) == + -1) { - if (unlikely(!afl_realloc(BUF_PARAMS(post_process), py_out_buf_size))) { - - PFATAL("alloc"); + PyErr_Print(); + FATAL( + "Python custom mutator: post_process call return value not a " + "bytes-like object"); } - memcpy(py->post_process_buf, PyByteArray_AsString(py_value), - py_out_buf_size); Py_DECREF(py_value); - *out_buf = py->post_process_buf; - return py_out_buf_size; + *out_buf = (u8 *)py->post_process_buf.buf; + return py->post_process_buf.len; } else { -- cgit v1.2.3 From e32b7eeb83c0571a2bdaadfd5b7b769fec1405cc Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 19 Nov 2020 16:14:19 +0100 Subject: fixed child not killed with -c --- src/afl-fuzz.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 1008f28c..b60908da 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -40,7 +40,7 @@ extern u64 time_spent_working; static void at_exit() { - int i; + s32 i, pid1 = 0, pid2 = 0; char *list[4] = {SHM_ENV_VAR, SHM_FUZZ_ENV_VAR, CMPLOG_SHM_ENV_VAR, NULL}; char *ptr; @@ -48,10 +48,10 @@ static void at_exit() { if (ptr && *ptr) unlink(ptr); ptr = getenv("__AFL_TARGET_PID1"); - if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL); + if (ptr && *ptr && (pid1 = atoi(ptr)) > 0) kill(pid1, SIGTERM); ptr = getenv("__AFL_TARGET_PID2"); - if (ptr && *ptr && (i = atoi(ptr)) > 0) kill(i, SIGKILL); + if (ptr && *ptr && (pid2 = atoi(ptr)) > 0) kill(pid2, SIGTERM); i = 0; while (list[i] != NULL) { @@ -75,6 +75,9 @@ static void at_exit() { } + if (pid1 > 0) { kill(pid1, SIGKILL); } + if (pid2 > 0) { kill(pid2, SIGKILL); } + } /* Display usage hints. */ -- cgit v1.2.3 From ed2f82eaf40a49d76d7615370ea8749c2f1fefaa Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 24 Nov 2020 16:13:58 +0100 Subject: fix compiler warning turned error on NetBSD --- src/afl-fuzz-run.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 95b3ee8a..b716b8c8 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -484,7 +484,7 @@ void sync_fuzzers(afl_state_t *afl) { DIR * sd; struct dirent *sd_ent; u32 sync_cnt = 0, synced = 0, entries = 0; - u8 path[PATH_MAX + 256]; + u8 path[PATH_MAX + 1 + NAME_MAX]; sd = opendir(afl->sync_dir); if (!sd) { PFATAL("Unable to open '%s'", afl->sync_dir); } -- cgit v1.2.3 From 27c3423fb6f1cf568cf0e50b16a82c035945ae7c Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 24 Nov 2020 19:38:55 +0100 Subject: test-pre.sh: remove old uses of afl-clang, afl-cc.c: add missing env.var. AFL_LLVM_LAF_ALL --- src/afl-cc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 19dc9a6a..1ad43c43 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -686,7 +686,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } if (getenv("AFL_NO_BUILTIN") || getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES") || - getenv("LAF_TRANSFORM_COMPARES") || lto_mode) { + getenv("LAF_TRANSFORM_COMPARES") || getenv("AFL_LLVM_LAF_ALL") || lto_mode) { cc_params[cc_par_cnt++] = "-fno-builtin-strcmp"; cc_params[cc_par_cnt++] = "-fno-builtin-strncmp"; @@ -1030,7 +1030,7 @@ int main(int argc, char **argv, char **envp) { if (instrument_mode == 0) instrument_mode = INSTRUMENT_PCGUARD; else if (instrument_mode != INSTRUMENT_PCGUARD) - FATAL("you can not set AFL_LLVM_INSTRUMENT and AFL_TRACE_PC together"); + FATAL("you cannot set AFL_LLVM_INSTRUMENT and AFL_TRACE_PC together"); } @@ -1049,7 +1049,7 @@ int main(int argc, char **argv, char **envp) { instrument_mode = INSTRUMENT_CFG; else if (instrument_mode != INSTRUMENT_CFG) FATAL( - "you can not set AFL_LLVM_INSTRUMENT and AFL_LLVM_INSTRIM together"); + "you cannot set AFL_LLVM_INSTRUMENT and AFL_LLVM_INSTRIM together"); } -- cgit v1.2.3 From ded80870a933b83d8186a160f7717641ce441a81 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sun, 1 Nov 2020 06:22:18 +0100 Subject: reenable afl-clang(++) --- src/afl-cc.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 1ad43c43..25ed923a 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -48,6 +48,7 @@ static u8 * obj_path; /* Path to runtime libraries */ static u8 **cc_params; /* Parameters passed to the real CC */ 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, lto_mode; static u8 compiler_mode, plusplus_mode, have_instr_env = 0; @@ -288,7 +289,15 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (compiler_mode >= GCC_PLUGIN) { - alt_cxx = "g++"; + if (compiler_mode == GCC) { + + alt_cxx = clang_mode ? "clang++" : "g++"; + + } else { + + alt_cxx = "g++"; + + } } else { @@ -313,7 +322,15 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (compiler_mode >= GCC_PLUGIN) { - alt_cc = "gcc"; + if (compiler_mode == GCC) { + + alt_cc = clang_mode ? "clang" : "gcc"; + + } else { + + alt_cc = "gcc"; + + } } else { @@ -337,6 +354,11 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = "-B"; cc_params[cc_par_cnt++] = obj_path; + if (clang_mode) { + + cc_params[cc_par_cnt++] = "-no-integrated-as"; + + } } if (compiler_mode == GCC_PLUGIN) { @@ -934,7 +956,9 @@ int main(int argc, char **argv, char **envp) { } else if (strncmp(callname, "afl-gcc", 7) == 0 || - strncmp(callname, "afl-g++", 7) == 0) { + strncmp(callname, "afl-g++", 7) == 0 || + + strncmp(callname, "afl-clang", 9) == 0) { compiler_mode = GCC; @@ -978,6 +1002,19 @@ int main(int argc, char **argv, char **envp) { } + + if (strncmp(callname, "afl-clang", 9) == 0) { + + clang_mode = 1; + + if (strncmp(callname, "afl-clang++", 11) == 0) { + + plusplus_mode = 1; + + } + + } + for (i = 1; i < argc; i++) { if (strncmp(argv[i], "--afl", 5) == 0) { -- cgit v1.2.3 From 0fd98ae8b070b05a72b2c47a76f4ea145f9d51c2 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 1 Nov 2020 21:34:08 +0100 Subject: added mutation introspection make target --- src/afl-fuzz-bitmap.c | 11 ++ src/afl-fuzz-extras.c | 16 +- src/afl-fuzz-one.c | 503 +++++++++++++++++++++++++++++++++++++++++++++++++- src/afl-fuzz.c | 17 ++ 4 files changed, 534 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 2653b9fd..735420c3 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -587,6 +587,11 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { add_to_queue(afl, queue_fn, len, 0); +#ifdef INTROSPECTION + fprintf(afl->introspection_file, "QUEUE %s = %s\n", afl->mutation, + afl->queue_top->fname); +#endif + if (hnb == 2) { afl->queue_top->has_new_cov = 1; @@ -659,6 +664,9 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { } ++afl->unique_tmouts; +#ifdef INTROSPECTION + fprintf(afl->introspection_file, "UNIQUE_TIMEOUT %s\n", afl->mutation); +#endif /* Before saving, we make sure that it's a genuine hang by re-running the target with a more generous timeout (unless the default timeout @@ -742,6 +750,9 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #endif /* ^!SIMPLE_FILES */ ++afl->unique_crashes; +#ifdef INTROSPECTION + fprintf(afl->introspection_file, "UNIQUE_CRASH %s\n", afl->mutation); +#endif if (unlikely(afl->infoexec)) { // if the user wants to be informed on new crashes - do that diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index adec986e..171cce96 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -423,8 +423,8 @@ void dedup_extras(afl_state_t *afl) { } if (afl->extras_cnt != orig_cnt) - afl->extras = ck_realloc((void **)&afl->extras, - afl->extras_cnt * sizeof(struct extra_data)); + afl->extras = afl_realloc_exact( + (void **)&afl->extras, afl->extras_cnt * sizeof(struct extra_data)); } @@ -462,16 +462,8 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { } - if (afl->extras) { - - afl->extras = ck_realloc((void **)&afl->extras, - (afl->extras_cnt + 1) * sizeof(struct extra_data)); - - } else { - - afl->extras = ck_alloc((afl->extras_cnt + 1) * sizeof(struct extra_data)); - - } + afl->extras = afl_realloc((void **)&afl->extras, + (afl->extras_cnt + 1) * sizeof(struct extra_data)); if (unlikely(!afl->extras)) { PFATAL("alloc"); } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 0f3393d2..5337b7f8 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -609,6 +609,11 @@ u8 fuzz_one_original(afl_state_t *afl) { FLIP_BIT(out_buf, afl->stage_cur); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT1 %u", + afl->queue_cur->fname, afl->stage_cur); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } FLIP_BIT(out_buf, afl->stage_cur); @@ -718,6 +723,11 @@ u8 fuzz_one_original(afl_state_t *afl) { FLIP_BIT(out_buf, afl->stage_cur); FLIP_BIT(out_buf, afl->stage_cur + 1); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT2 %u", + afl->queue_cur->fname, afl->stage_cur); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } FLIP_BIT(out_buf, afl->stage_cur); @@ -747,6 +757,11 @@ u8 fuzz_one_original(afl_state_t *afl) { FLIP_BIT(out_buf, afl->stage_cur + 2); FLIP_BIT(out_buf, afl->stage_cur + 3); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT4 %u", + afl->queue_cur->fname, afl->stage_cur); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } FLIP_BIT(out_buf, afl->stage_cur); @@ -802,6 +817,11 @@ u8 fuzz_one_original(afl_state_t *afl) { out_buf[afl->stage_cur] ^= 0xFF; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT8 %u", + afl->queue_cur->fname, afl->stage_cur); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } /* We also use this stage to pull off a simple trick: we identify @@ -889,6 +909,11 @@ u8 fuzz_one_original(afl_state_t *afl) { *(u16 *)(out_buf + i) ^= 0xFFFF; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT16 %u", + afl->queue_cur->fname, afl->stage_cur); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -927,6 +952,11 @@ u8 fuzz_one_original(afl_state_t *afl) { *(u32 *)(out_buf + i) ^= 0xFFFFFFFF; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT32 %u", + afl->queue_cur->fname, afl->stage_cur); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -985,6 +1015,11 @@ skip_bitflip: afl->stage_cur_val = j; out_buf[i] = orig + j; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH8+ %u %u", + afl->queue_cur->fname, i, j); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -1001,6 +1036,11 @@ skip_bitflip: afl->stage_cur_val = -j; out_buf[i] = orig - j; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH8- %u %u", + afl->queue_cur->fname, i, j); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -1065,6 +1105,11 @@ skip_bitflip: afl->stage_cur_val = j; *(u16 *)(out_buf + i) = orig + j; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH16+ %u %u", + afl->queue_cur->fname, i, j); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -1079,6 +1124,11 @@ skip_bitflip: afl->stage_cur_val = -j; *(u16 *)(out_buf + i) = orig - j; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH16- %u %u", + afl->queue_cur->fname, i, j); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -1097,6 +1147,11 @@ skip_bitflip: afl->stage_cur_val = j; *(u16 *)(out_buf + i) = SWAP16(SWAP16(orig) + j); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH16+BE %u %u", + afl->queue_cur->fname, i, j); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -1111,6 +1166,11 @@ skip_bitflip: afl->stage_cur_val = -j; *(u16 *)(out_buf + i) = SWAP16(SWAP16(orig) - j); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH16-BE %u %u", + afl->queue_cur->fname, i, j); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -1174,6 +1234,11 @@ skip_bitflip: afl->stage_cur_val = j; *(u32 *)(out_buf + i) = orig + j; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH32+ %u %u", + afl->queue_cur->fname, i, j); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -1188,6 +1253,11 @@ skip_bitflip: afl->stage_cur_val = -j; *(u32 *)(out_buf + i) = orig - j; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH32- %u %u", + afl->queue_cur->fname, i, j); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -1206,6 +1276,11 @@ skip_bitflip: afl->stage_cur_val = j; *(u32 *)(out_buf + i) = SWAP32(SWAP32(orig) + j); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH32+BE %u %u", + afl->queue_cur->fname, i, j); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -1220,6 +1295,11 @@ skip_bitflip: afl->stage_cur_val = -j; *(u32 *)(out_buf + i) = SWAP32(SWAP32(orig) - j); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH32-BE %u %u", + afl->queue_cur->fname, i, j); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -1287,6 +1367,11 @@ skip_arith: afl->stage_cur_val = interesting_8[j]; out_buf[i] = interesting_8[j]; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s INTERESTING8 %u %u", + afl->queue_cur->fname, i, j); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } out_buf[i] = orig; @@ -1342,6 +1427,11 @@ skip_arith: *(u16 *)(out_buf + i) = interesting_16[j]; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s INTERESTING16 %u %u", + afl->queue_cur->fname, i, j); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -1358,6 +1448,11 @@ skip_arith: afl->stage_val_type = STAGE_VAL_BE; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s INTERESTING16BE %u %u", afl->queue_cur->fname, i, j); +#endif + *(u16 *)(out_buf + i) = SWAP16(interesting_16[j]); if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -1421,6 +1516,11 @@ skip_arith: *(u32 *)(out_buf + i) = interesting_32[j]; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s INTERESTING32 %u %u", + afl->queue_cur->fname, i, j); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -1437,6 +1537,11 @@ skip_arith: afl->stage_val_type = STAGE_VAL_BE; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s INTERESTING32BE %u %u", afl->queue_cur->fname, i, j); +#endif + *(u32 *)(out_buf + i) = SWAP32(interesting_32[j]); if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -1510,6 +1615,12 @@ skip_interest: last_len = afl->extras[j].len; memcpy(out_buf + i, afl->extras[j].data, last_len); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s EXTRAS overwrite %u %u:%s", afl->queue_cur->fname, i, j, + afl->extras[j].data); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -1557,6 +1668,12 @@ skip_interest: /* Copy tail */ memcpy(ex_tmp + i + afl->extras[j].len, out_buf + i, len - i); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s EXTRAS insert %u %u:%s", afl->queue_cur->fname, i, j, + afl->extras[j].data); +#endif + if (common_fuzz_stuff(afl, ex_tmp, len + afl->extras[j].len)) { goto abandon_entry; @@ -1614,6 +1731,12 @@ skip_user_extras: last_len = afl->a_extras[j].len; memcpy(out_buf + i, afl->a_extras[j].data, last_len); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s AUTO_EXTRAS overwrite %u %u:%s", afl->queue_cur->fname, i, j, + afl->a_extras[j].data); +#endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -1675,7 +1798,7 @@ custom_mutator_stage: for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { - struct queue_entry *target; + struct queue_entry *target = NULL; u32 tid; u8 * new_buf = NULL; u32 target_len = 0; @@ -1717,6 +1840,12 @@ custom_mutator_stage: if (mutated_size > 0) { +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s CUSTOM %s", + afl->queue_cur->fname, + target != NULL ? (char *)target->fname : "none"); +#endif + if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) { goto abandon_entry; @@ -1866,6 +1995,11 @@ havoc_stage: afl->stage_cur_val = use_stacking; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s HAVOC %u", + afl->queue_cur->fname, use_stacking); +#endif + for (i = 0; i < use_stacking; ++i) { if (afl->custom_mutators_count) { @@ -1909,6 +2043,10 @@ havoc_stage: /* Flip a single bit somewhere. Spooky! */ +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP_BIT1"); + strcat(afl->mutation, afl->m_tmp); +#endif FLIP_BIT(out_buf, rand_below(afl, temp_len << 3)); break; @@ -1916,6 +2054,10 @@ havoc_stage: /* Set byte to interesting value. */ +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING8"); + strcat(afl->mutation, afl->m_tmp); +#endif out_buf[rand_below(afl, temp_len)] = interesting_8[rand_below(afl, sizeof(interesting_8))]; break; @@ -1928,11 +2070,19 @@ havoc_stage: if (rand_below(afl, 2)) { +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16"); + strcat(afl->mutation, afl->m_tmp); +#endif *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]; } else { +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16BE"); + strcat(afl->mutation, afl->m_tmp); +#endif *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = SWAP16( interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]); @@ -1948,11 +2098,19 @@ havoc_stage: if (rand_below(afl, 2)) { +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32"); + strcat(afl->mutation, afl->m_tmp); +#endif *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]; } else { +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32BE"); + strcat(afl->mutation, afl->m_tmp); +#endif *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = SWAP32( interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]); @@ -1964,6 +2122,10 @@ havoc_stage: /* Randomly subtract from byte. */ +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH8-"); + strcat(afl->mutation, afl->m_tmp); +#endif out_buf[rand_below(afl, temp_len)] -= 1 + rand_below(afl, ARITH_MAX); break; @@ -1971,6 +2133,10 @@ havoc_stage: /* Randomly add to byte. */ +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH8+"); + strcat(afl->mutation, afl->m_tmp); +#endif out_buf[rand_below(afl, temp_len)] += 1 + rand_below(afl, ARITH_MAX); break; @@ -1984,6 +2150,10 @@ havoc_stage: u32 pos = rand_below(afl, temp_len - 1); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16-_%u", pos); + strcat(afl->mutation, afl->m_tmp); +#endif *(u16 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); } else { @@ -1991,6 +2161,11 @@ havoc_stage: u32 pos = rand_below(afl, temp_len - 1); u16 num = 1 + rand_below(afl, ARITH_MAX); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16-BE_%u_%u", pos, + num); + strcat(afl->mutation, afl->m_tmp); +#endif *(u16 *)(out_buf + pos) = SWAP16(SWAP16(*(u16 *)(out_buf + pos)) - num); @@ -2008,6 +2183,10 @@ havoc_stage: u32 pos = rand_below(afl, temp_len - 1); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+_%u", pos); + strcat(afl->mutation, afl->m_tmp); +#endif *(u16 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); } else { @@ -2015,6 +2194,11 @@ havoc_stage: u32 pos = rand_below(afl, temp_len - 1); u16 num = 1 + rand_below(afl, ARITH_MAX); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+BE_%u_%u", pos, + num); + strcat(afl->mutation, afl->m_tmp); +#endif *(u16 *)(out_buf + pos) = SWAP16(SWAP16(*(u16 *)(out_buf + pos)) + num); @@ -2032,6 +2216,10 @@ havoc_stage: u32 pos = rand_below(afl, temp_len - 3); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32-_%u", pos); + strcat(afl->mutation, afl->m_tmp); +#endif *(u32 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); } else { @@ -2039,6 +2227,11 @@ havoc_stage: u32 pos = rand_below(afl, temp_len - 3); u32 num = 1 + rand_below(afl, ARITH_MAX); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32-BE_%u_%u", pos, + num); + strcat(afl->mutation, afl->m_tmp); +#endif *(u32 *)(out_buf + pos) = SWAP32(SWAP32(*(u32 *)(out_buf + pos)) - num); @@ -2056,6 +2249,10 @@ havoc_stage: u32 pos = rand_below(afl, temp_len - 3); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+_%u", pos); + strcat(afl->mutation, afl->m_tmp); +#endif *(u32 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); } else { @@ -2063,6 +2260,11 @@ havoc_stage: u32 pos = rand_below(afl, temp_len - 3); u32 num = 1 + rand_below(afl, ARITH_MAX); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+BE_%u_%u", pos, + num); + strcat(afl->mutation, afl->m_tmp); +#endif *(u32 *)(out_buf + pos) = SWAP32(SWAP32(*(u32 *)(out_buf + pos)) + num); @@ -2076,6 +2278,10 @@ havoc_stage: why not. We use XOR with 1-255 to eliminate the possibility of a no-op. */ +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " RAND8"); + strcat(afl->mutation, afl->m_tmp); +#endif out_buf[rand_below(afl, temp_len)] ^= 1 + rand_below(afl, 255); break; @@ -2095,6 +2301,11 @@ havoc_stage: del_from = rand_below(afl, temp_len - del_len + 1); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " DEL_%u_%u", del_from, + del_len); + strcat(afl->mutation, afl->m_tmp); +#endif memmove(out_buf + del_from, out_buf + del_from + del_len, temp_len - del_from - del_len); @@ -2128,6 +2339,12 @@ havoc_stage: clone_to = rand_below(afl, temp_len); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE_%s_%u_%u_%u", + actually_clone ? "clone" : "insert", clone_from, clone_to, + clone_len); + strcat(afl->mutation, afl->m_tmp); +#endif new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), temp_len + clone_len); if (unlikely(!new_buf)) { PFATAL("alloc"); } @@ -2181,12 +2398,23 @@ havoc_stage: if (copy_from != copy_to) { +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " OVERWRITE_COPY_%u_%u_%u", copy_from, copy_to, + copy_len); + strcat(afl->mutation, afl->m_tmp); +#endif memmove(out_buf + copy_to, out_buf + copy_from, copy_len); } } else { +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " OVERWRITE_FIXED_%u_%u_%u", copy_from, copy_to, copy_len); + strcat(afl->mutation, afl->m_tmp); +#endif memset(out_buf + copy_to, rand_below(afl, 2) ? rand_below(afl, 256) : out_buf[rand_below(afl, temp_len)], @@ -2222,6 +2450,12 @@ havoc_stage: if ((s32)extra_len > temp_len) { break; } insert_at = rand_below(afl, temp_len - extra_len + 1); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " AUTO_EXTRA_OVERWRITE_%u_%u_%s", insert_at, extra_len, + afl->a_extras[use_extra].data); + strcat(afl->mutation, afl->m_tmp); +#endif memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, extra_len); @@ -2236,6 +2470,12 @@ havoc_stage: if ((s32)extra_len > temp_len) { break; } insert_at = rand_below(afl, temp_len - extra_len + 1); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " EXTRA_OVERWRITE_%u_%u_%s", insert_at, extra_len, + afl->a_extras[use_extra].data); + strcat(afl->mutation, afl->m_tmp); +#endif memcpy(out_buf + insert_at, afl->extras[use_extra].data, extra_len); @@ -2258,12 +2498,23 @@ havoc_stage: use_extra = rand_below(afl, afl->a_extras_cnt); extra_len = afl->a_extras[use_extra].len; ptr = afl->a_extras[use_extra].data; +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " AUTO_EXTRA_INSERT_%u_%u_%s", insert_at, extra_len, + ptr); + strcat(afl->mutation, afl->m_tmp); +#endif } else { use_extra = rand_below(afl, afl->extras_cnt); extra_len = afl->extras[use_extra].len; ptr = afl->extras[use_extra].data; +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " EXTRA_INSERT_%u_%u_%s", insert_at, extra_len, ptr); + strcat(afl->mutation, afl->m_tmp); +#endif } @@ -2324,6 +2575,12 @@ havoc_stage: copy_from = rand_below(afl, new_len - copy_len + 1); copy_to = rand_below(afl, temp_len - copy_len + 1); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " SPLICE_OVERWRITE_%u_%u_%u_%s", copy_from, copy_to, + copy_len, target->fname); + strcat(afl->mutation, afl->m_tmp); +#endif memmove(out_buf + copy_to, new_buf + copy_from, copy_len); } else { @@ -2340,6 +2597,12 @@ havoc_stage: temp_len + clone_len + 1); if (unlikely(!temp_buf)) { PFATAL("alloc"); } +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " SPLICE_INSERT_%u_%u_%u_%s", clone_from, clone_to, + clone_len, target->fname); + strcat(afl->mutation, afl->m_tmp); +#endif /* Head */ memcpy(temp_buf, out_buf, clone_to); @@ -2755,6 +3018,10 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { FLIP_BIT(out_buf, afl->stage_cur); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT1 %u", + afl->queue_cur->fname, afl->stage_cur); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } FLIP_BIT(out_buf, afl->stage_cur); @@ -2864,6 +3131,10 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { FLIP_BIT(out_buf, afl->stage_cur); FLIP_BIT(out_buf, afl->stage_cur + 1); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT2 %u", + afl->queue_cur->fname, afl->stage_cur); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } FLIP_BIT(out_buf, afl->stage_cur); @@ -2893,6 +3164,10 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { FLIP_BIT(out_buf, afl->stage_cur + 2); FLIP_BIT(out_buf, afl->stage_cur + 3); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT4 %u", + afl->queue_cur->fname, afl->stage_cur); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } FLIP_BIT(out_buf, afl->stage_cur); @@ -2948,6 +3223,10 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { out_buf[afl->stage_cur] ^= 0xFF; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT8 %u", + afl->queue_cur->fname, afl->stage_cur); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } /* We also use this stage to pull off a simple trick: we identify @@ -3035,6 +3314,10 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { *(u16 *)(out_buf + i) ^= 0xFFFF; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT16 %u", + afl->queue_cur->fname, afl->stage_cur); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3073,6 +3356,10 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { *(u32 *)(out_buf + i) ^= 0xFFFFFFFF; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT32 %u", + afl->queue_cur->fname, afl->stage_cur); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3131,6 +3418,10 @@ skip_bitflip: afl->stage_cur_val = j; out_buf[i] = orig + j; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH8+ %u %u", + afl->queue_cur->fname, i, j); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3147,6 +3438,10 @@ skip_bitflip: afl->stage_cur_val = -j; out_buf[i] = orig - j; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH8- %u %u", + afl->queue_cur->fname, i, j); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3211,6 +3506,10 @@ skip_bitflip: afl->stage_cur_val = j; *(u16 *)(out_buf + i) = orig + j; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH16+ %u %u", + afl->queue_cur->fname, i, j); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3225,6 +3524,10 @@ skip_bitflip: afl->stage_cur_val = -j; *(u16 *)(out_buf + i) = orig - j; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH16- %u %u", + afl->queue_cur->fname, i, j); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3243,6 +3546,10 @@ skip_bitflip: afl->stage_cur_val = j; *(u16 *)(out_buf + i) = SWAP16(SWAP16(orig) + j); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s MOPT_ARITH16+BE %u %u", afl->queue_cur->fname, i, j); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3257,6 +3564,10 @@ skip_bitflip: afl->stage_cur_val = -j; *(u16 *)(out_buf + i) = SWAP16(SWAP16(orig) - j); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s MOPT_ARITH16-BE %u %u", afl->queue_cur->fname, i, j); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3320,6 +3631,10 @@ skip_bitflip: afl->stage_cur_val = j; *(u32 *)(out_buf + i) = orig + j; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH32+ %u %u", + afl->queue_cur->fname, i, j); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3334,6 +3649,10 @@ skip_bitflip: afl->stage_cur_val = -j; *(u32 *)(out_buf + i) = orig - j; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH32- %u %u", + afl->queue_cur->fname, i, j); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3352,6 +3671,10 @@ skip_bitflip: afl->stage_cur_val = j; *(u32 *)(out_buf + i) = SWAP32(SWAP32(orig) + j); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s MOPT_ARITH32+BE %u %u", afl->queue_cur->fname, i, j); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3366,6 +3689,10 @@ skip_bitflip: afl->stage_cur_val = -j; *(u32 *)(out_buf + i) = SWAP32(SWAP32(orig) - j); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s MOPT_ARITH32-BE %u %u", afl->queue_cur->fname, i, j); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3433,6 +3760,10 @@ skip_arith: afl->stage_cur_val = interesting_8[j]; out_buf[i] = interesting_8[j]; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s MOPT_INTERESTING8 %u %u", afl->queue_cur->fname, i, j); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } out_buf[i] = orig; @@ -3488,6 +3819,10 @@ skip_arith: *(u16 *)(out_buf + i) = interesting_16[j]; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s MOPT_INTERESTING16 %u %u", afl->queue_cur->fname, i, j); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3504,6 +3839,10 @@ skip_arith: afl->stage_val_type = STAGE_VAL_BE; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s MOPT_INTERESTING16BE %u %u", afl->queue_cur->fname, i, j); +#endif *(u16 *)(out_buf + i) = SWAP16(interesting_16[j]); if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3567,6 +3906,10 @@ skip_arith: *(u32 *)(out_buf + i) = interesting_32[j]; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s MOPT_INTERESTING32 %u %u", afl->queue_cur->fname, i, j); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3583,6 +3926,10 @@ skip_arith: afl->stage_val_type = STAGE_VAL_BE; +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s MOPT_INTERESTING32BE %u %u", afl->queue_cur->fname, i, j); +#endif *(u32 *)(out_buf + i) = SWAP32(interesting_32[j]); if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3656,6 +4003,11 @@ skip_interest: last_len = afl->extras[j].len; memcpy(out_buf + i, afl->extras[j].data, last_len); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s MOPT_EXTRAS overwrite %u %u:%s", afl->queue_cur->fname, i, j, + afl->extras[j].data); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3703,6 +4055,11 @@ skip_interest: /* Copy tail */ memcpy(ex_tmp + i + afl->extras[j].len, out_buf + i, len - i); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s MOPT_EXTRAS insert %u %u:%s", afl->queue_cur->fname, i, j, + afl->extras[j].data); +#endif if (common_fuzz_stuff(afl, ex_tmp, len + afl->extras[j].len)) { goto abandon_entry; @@ -3759,6 +4116,11 @@ skip_user_extras: last_len = afl->a_extras[j].len; memcpy(out_buf + i, afl->a_extras[j].data, last_len); +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), + "%s MOPT_AUTO_EXTRAS overwrite %u %u:%s", afl->queue_cur->fname, + i, j, afl->a_extras[j].data); +#endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3885,6 +4247,11 @@ pacemaker_fuzzing: } +#ifdef INTROSPECTION + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_HAVOC %u", + afl->queue_cur->fname, use_stacking); +#endif + for (i = 0; i < use_stacking; ++i) { switch (select_algorithm(afl)) { @@ -3893,6 +4260,10 @@ pacemaker_fuzzing: /* Flip a single bit somewhere. Spooky! */ FLIP_BIT(out_buf, rand_below(afl, temp_len << 3)); MOpt_globals.cycles_v2[STAGE_FLIP1] += 1; +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP_BIT1"); + strcat(afl->mutation, afl->m_tmp); +#endif break; case 1: @@ -3901,6 +4272,10 @@ pacemaker_fuzzing: FLIP_BIT(out_buf, temp_len_puppet); FLIP_BIT(out_buf, temp_len_puppet + 1); MOpt_globals.cycles_v2[STAGE_FLIP2] += 1; +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP_BIT2"); + strcat(afl->mutation, afl->m_tmp); +#endif break; case 2: @@ -3911,24 +4286,40 @@ pacemaker_fuzzing: FLIP_BIT(out_buf, temp_len_puppet + 2); FLIP_BIT(out_buf, temp_len_puppet + 3); MOpt_globals.cycles_v2[STAGE_FLIP4] += 1; +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP_BIT4"); + strcat(afl->mutation, afl->m_tmp); +#endif break; case 3: if (temp_len < 4) { break; } out_buf[rand_below(afl, temp_len)] ^= 0xFF; MOpt_globals.cycles_v2[STAGE_FLIP8] += 1; +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP_BIT8"); + strcat(afl->mutation, afl->m_tmp); +#endif break; case 4: if (temp_len < 8) { break; } *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) ^= 0xFFFF; MOpt_globals.cycles_v2[STAGE_FLIP16] += 1; +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP_BIT16"); + strcat(afl->mutation, afl->m_tmp); +#endif break; case 5: if (temp_len < 8) { break; } *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) ^= 0xFFFFFFFF; MOpt_globals.cycles_v2[STAGE_FLIP32] += 1; +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP_BIT32"); + strcat(afl->mutation, afl->m_tmp); +#endif break; case 6: @@ -3937,6 +4328,10 @@ pacemaker_fuzzing: out_buf[rand_below(afl, temp_len)] += 1 + rand_below(afl, ARITH_MAX); MOpt_globals.cycles_v2[STAGE_ARITH8] += 1; +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH+-"); + strcat(afl->mutation, afl->m_tmp); +#endif break; case 7: @@ -3946,11 +4341,20 @@ pacemaker_fuzzing: u32 pos = rand_below(afl, temp_len - 1); *(u16 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16-%u", pos); + strcat(afl->mutation, afl->m_tmp); +#endif } else { u32 pos = rand_below(afl, temp_len - 1); u16 num = 1 + rand_below(afl, ARITH_MAX); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16BE-%u-%u", + pos, num); + strcat(afl->mutation, afl->m_tmp); +#endif *(u16 *)(out_buf + pos) = SWAP16(SWAP16(*(u16 *)(out_buf + pos)) - num); @@ -3960,12 +4364,21 @@ pacemaker_fuzzing: if (rand_below(afl, 2)) { u32 pos = rand_below(afl, temp_len - 1); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+%u", pos); + strcat(afl->mutation, afl->m_tmp); +#endif *(u16 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); } else { u32 pos = rand_below(afl, temp_len - 1); u16 num = 1 + rand_below(afl, ARITH_MAX); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16BE+%u-%u", + pos, num); + strcat(afl->mutation, afl->m_tmp); +#endif *(u16 *)(out_buf + pos) = SWAP16(SWAP16(*(u16 *)(out_buf + pos)) + num); @@ -3980,12 +4393,21 @@ pacemaker_fuzzing: if (rand_below(afl, 2)) { u32 pos = rand_below(afl, temp_len - 3); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32-%u", pos); + strcat(afl->mutation, afl->m_tmp); +#endif *(u32 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); } else { u32 pos = rand_below(afl, temp_len - 3); u32 num = 1 + rand_below(afl, ARITH_MAX); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32BE-%u-%u", + pos, num); + strcat(afl->mutation, afl->m_tmp); +#endif *(u32 *)(out_buf + pos) = SWAP32(SWAP32(*(u32 *)(out_buf + pos)) - num); @@ -3996,12 +4418,21 @@ pacemaker_fuzzing: if (rand_below(afl, 2)) { u32 pos = rand_below(afl, temp_len - 3); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+%u", pos); + strcat(afl->mutation, afl->m_tmp); +#endif *(u32 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); } else { u32 pos = rand_below(afl, temp_len - 3); u32 num = 1 + rand_below(afl, ARITH_MAX); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32BE+%u-%u", + pos, num); + strcat(afl->mutation, afl->m_tmp); +#endif *(u32 *)(out_buf + pos) = SWAP32(SWAP32(*(u32 *)(out_buf + pos)) + num); @@ -4016,6 +4447,10 @@ pacemaker_fuzzing: out_buf[rand_below(afl, temp_len)] = interesting_8[rand_below(afl, sizeof(interesting_8))]; MOpt_globals.cycles_v2[STAGE_INTEREST8] += 1; +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING8"); + strcat(afl->mutation, afl->m_tmp); +#endif break; case 10: @@ -4023,12 +4458,20 @@ pacemaker_fuzzing: if (temp_len < 8) { break; } if (rand_below(afl, 2)) { +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16"); + strcat(afl->mutation, afl->m_tmp); +#endif *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]; } else { +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16BE"); + strcat(afl->mutation, afl->m_tmp); +#endif *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = SWAP16(interesting_16[rand_below( afl, sizeof(interesting_16) >> 1)]); @@ -4045,12 +4488,20 @@ pacemaker_fuzzing: if (rand_below(afl, 2)) { +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32"); + strcat(afl->mutation, afl->m_tmp); +#endif *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]; } else { +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32BE"); + strcat(afl->mutation, afl->m_tmp); +#endif *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = SWAP32(interesting_32[rand_below( afl, sizeof(interesting_32) >> 2)]); @@ -4068,6 +4519,10 @@ pacemaker_fuzzing: out_buf[rand_below(afl, temp_len)] ^= 1 + rand_below(afl, 255); MOpt_globals.cycles_v2[STAGE_RANDOMBYTE] += 1; +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " RAND8"); + strcat(afl->mutation, afl->m_tmp); +#endif break; case 13: { @@ -4091,6 +4546,11 @@ pacemaker_fuzzing: temp_len -= del_len; MOpt_globals.cycles_v2[STAGE_DELETEBYTE] += 1; +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " DEL-%u%u", del_from, + del_len); + strcat(afl->mutation, afl->m_tmp); +#endif break; } @@ -4120,6 +4580,12 @@ pacemaker_fuzzing: clone_to = rand_below(afl, temp_len); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE_%s_%u_%u_%u", + actually_clone ? "clone" : "insert", clone_from, + clone_to, clone_len); + strcat(afl->mutation, afl->m_tmp); +#endif new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), temp_len + clone_len); if (unlikely(!new_buf)) { PFATAL("alloc"); } @@ -4175,12 +4641,24 @@ pacemaker_fuzzing: if (copy_from != copy_to) { +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " OVERWRITE_COPY_%u_%u_%u", copy_from, copy_to, + copy_len); + strcat(afl->mutation, afl->m_tmp); +#endif memmove(out_buf + copy_to, out_buf + copy_from, copy_len); } } else { +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " OVERWRITE_FIXED_%u_%u_%u", copy_from, copy_to, + copy_len); + strcat(afl->mutation, afl->m_tmp); +#endif memset(out_buf + copy_to, rand_below(afl, 2) ? rand_below(afl, 256) : out_buf[rand_below(afl, temp_len)], @@ -4212,6 +4690,12 @@ pacemaker_fuzzing: if (extra_len > (u32)temp_len) break; u32 insert_at = rand_below(afl, temp_len - extra_len + 1); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " AUTO_EXTRA_OVERWRITE_%u_%u_%s", insert_at, extra_len, + afl->a_extras[use_extra].data); + strcat(afl->mutation, afl->m_tmp); +#endif memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, extra_len); @@ -4225,6 +4709,12 @@ pacemaker_fuzzing: if (extra_len > (u32)temp_len) break; u32 insert_at = rand_below(afl, temp_len - extra_len + 1); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " EXTRA_OVERWRITE_%u_%u_%s", insert_at, extra_len, + afl->a_extras[use_extra].data); + strcat(afl->mutation, afl->m_tmp); +#endif memcpy(out_buf + insert_at, afl->extras[use_extra].data, extra_len); @@ -4254,12 +4744,23 @@ pacemaker_fuzzing: use_extra = rand_below(afl, afl->a_extras_cnt); extra_len = afl->a_extras[use_extra].len; ptr = afl->a_extras[use_extra].data; +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " AUTO_EXTRA_INSERT_%u_%u_%s", insert_at, extra_len, + ptr); + strcat(afl->mutation, afl->m_tmp); +#endif } else { use_extra = rand_below(afl, afl->extras_cnt); extra_len = afl->extras[use_extra].len; ptr = afl->extras[use_extra].data; +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " EXTRA_INSERT_%u_%u_%s", insert_at, extra_len, ptr); + strcat(afl->mutation, afl->m_tmp); +#endif } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index cad26841..575e6b74 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -236,6 +236,10 @@ static void usage(u8 *argv0, int more_help) { SAYF("Compiled with PROFILING\n\n"); #endif +#ifdef INTROSPECTION + SAYF("Compiled with INTROSPECTION\n\n"); +#endif + #ifdef _DEBUG SAYF("Compiled with _DEBUG\n\n"); #endif @@ -1462,6 +1466,19 @@ int main(int argc, char **argv_orig, char **envp) { u32 prev_queued_paths = 0; u8 skipped_fuzz; + #ifdef INTROSPECTION + char ifn[4096]; + snprintf(ifn, sizeof(ifn), "%s/introspection.txt", afl->out_dir); + if ((afl->introspection_file = fopen(ifn, "w")) == NULL) { + + PFATAL("could not create '%s'", ifn); + + } + + setvbuf(afl->introspection_file, NULL, _IONBF, 0); + OKF("Writing mutation introspection to '%s'", ifn); + #endif + while (likely(!afl->stop_soon)) { cull_queue(afl); -- cgit v1.2.3 From 416e01d3c6277988ed39e67f9404bd7a6034820b Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 2 Nov 2020 11:04:35 +0100 Subject: match mopt to havoc --- src/afl-fuzz-one.c | 209 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 159 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 5337b7f8..e4016773 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -29,11 +29,9 @@ /* MOpt */ -static int select_algorithm(afl_state_t *afl) { +static int select_algorithm(afl_state_t *afl, u32 max_algorithm) { - int i_puppet, j_puppet = 0, operator_number = operator_num; - - if (!afl->extras_cnt && !afl->a_extras_cnt) operator_number -= 2; + int i_puppet, j_puppet = 0, operator_number = max_algorithm; double range_sele = (double)afl->probability_now[afl->swarm_now][operator_number - 1]; @@ -502,6 +500,8 @@ u8 fuzz_one_original(afl_state_t *afl) { if (unlikely(!afl->non_instrumented_mode && !afl->queue_cur->trim_done && !afl->disable_trim)) { + u32 old_len = afl->queue_cur->len; + u8 res = trim_case(afl, afl->queue_cur, in_buf); orig_in = in_buf = queue_testcase_get(afl, afl->queue_cur); @@ -524,6 +524,9 @@ u8 fuzz_one_original(afl_state_t *afl) { len = afl->queue_cur->len; + /* maybe current entry is not ready for splicing anymore */ + if (unlikely(len <= 4 && old_len > 4)) afl->ready_for_splicing_count--; + } memcpy(out_buf, in_buf, len); @@ -537,7 +540,7 @@ u8 fuzz_one_original(afl_state_t *afl) { else orig_perf = perf_score = calculate_score(afl, afl->queue_cur); - if (unlikely(perf_score == 0)) { goto abandon_entry; } + if (unlikely(perf_score <= 0)) { goto abandon_entry; } if (unlikely(afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized)) { @@ -1976,7 +1979,7 @@ havoc_stage: /* add expensive havoc cases here, they are activated after a full cycle without finds happened */ - r_max += 1; + r_max++; } @@ -1985,7 +1988,7 @@ havoc_stage: /* add expensive havoc cases here if there is no findings in the last 5s */ - r_max += 1; + r_max++; } @@ -2396,7 +2399,7 @@ havoc_stage: if (likely(rand_below(afl, 4))) { - if (copy_from != copy_to) { + if (likely(copy_from != copy_to)) { #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), @@ -2445,11 +2448,10 @@ havoc_stage: u32 use_extra = rand_below(afl, afl->a_extras_cnt); u32 extra_len = afl->a_extras[use_extra].len; - u32 insert_at; if ((s32)extra_len > temp_len) { break; } - insert_at = rand_below(afl, temp_len - extra_len + 1); + u32 insert_at = rand_below(afl, temp_len - extra_len + 1); #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), " AUTO_EXTRA_OVERWRITE_%u_%u_%s", insert_at, extra_len, @@ -2465,11 +2467,10 @@ havoc_stage: u32 use_extra = rand_below(afl, afl->extras_cnt); u32 extra_len = afl->extras[use_extra].len; - u32 insert_at; if ((s32)extra_len > temp_len) { break; } - insert_at = rand_below(afl, temp_len - extra_len + 1); + u32 insert_at = rand_below(afl, temp_len - extra_len + 1); #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), " EXTRA_OVERWRITE_%u_%u_%s", insert_at, extra_len, @@ -2816,7 +2817,8 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { possibly skip to them at the expense of already-fuzzed or non-favored cases. */ - if ((afl->queue_cur->was_fuzzed || !afl->queue_cur->favored) && + if (((afl->queue_cur->was_fuzzed > 0 || afl->queue_cur->fuzz_level > 0) || + !afl->queue_cur->favored) && rand_below(afl, 100) < SKIP_TO_NEW_PROB) { return 1; @@ -2831,13 +2833,14 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { The odds of skipping stuff are higher for already-fuzzed inputs and lower for never-fuzzed entries. */ - if (afl->queue_cycle > 1 && !afl->queue_cur->was_fuzzed) { + if (afl->queue_cycle > 1 && + (afl->queue_cur->fuzz_level == 0 || afl->queue_cur->was_fuzzed)) { - if (rand_below(afl, 100) < SKIP_NFAV_NEW_PROB) { return 1; } + if (likely(rand_below(afl, 100) < SKIP_NFAV_NEW_PROB)) { return 1; } } else { - if (rand_below(afl, 100) < SKIP_NFAV_OLD_PROB) { return 1; } + if (likely(rand_below(afl, 100) < SKIP_NFAV_OLD_PROB)) { return 1; } } @@ -2856,16 +2859,19 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { /* Map the test case into memory. */ orig_in = in_buf = queue_testcase_get(afl, afl->queue_cur); len = afl->queue_cur->len; + out_buf = afl_realloc(AFL_BUF_PARAM(out), len); if (unlikely(!out_buf)) { PFATAL("alloc"); } + afl->subseq_tmouts = 0; + afl->cur_depth = afl->queue_cur->depth; /******************************************* * CALIBRATION (only if failed earlier on) * *******************************************/ - if (afl->queue_cur->cal_failed) { + if (unlikely(afl->queue_cur->cal_failed)) { u8 res = FSRV_RUN_TMOUT; @@ -2897,7 +2903,8 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { * TRIMMING * ************/ - if (!afl->non_instrumented_mode && !afl->queue_cur->trim_done) { + if (unlikely(!afl->non_instrumented_mode && !afl->queue_cur->trim_done && + !afl->disable_trim)) { u32 old_len = afl->queue_cur->len; @@ -2939,6 +2946,8 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { else orig_perf = perf_score = calculate_score(afl, afl->queue_cur); + if (unlikely(perf_score <= 0)) { goto abandon_entry; } + if (unlikely(afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized)) { if (input_to_state_stage(afl, in_buf, out_buf, len, @@ -2968,8 +2977,8 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { this entry ourselves (was_fuzzed), or if it has gone through deterministic testing in earlier, resumed runs (passed_det). */ - if (afl->skip_deterministic || afl->queue_cur->was_fuzzed || - afl->queue_cur->passed_det) { + if (likely(afl->skip_deterministic || afl->queue_cur->was_fuzzed || + afl->queue_cur->passed_det)) { goto havoc_stage; @@ -2978,8 +2987,9 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { /* Skip deterministic fuzzing if exec path checksum puts this out of scope for this main instance. */ - if (afl->main_node_max && (afl->queue_cur->exec_cksum % afl->main_node_max) != - afl->main_node_id - 1) { + if (unlikely(afl->main_node_max && + (afl->queue_cur->exec_cksum % afl->main_node_max) != + afl->main_node_id - 1)) { goto havoc_stage; @@ -4008,6 +4018,7 @@ skip_interest: "%s MOPT_EXTRAS overwrite %u %u:%s", afl->queue_cur->fname, i, j, afl->extras[j].data); #endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -4060,6 +4071,7 @@ skip_interest: "%s MOPT_EXTRAS insert %u %u:%s", afl->queue_cur->fname, i, j, afl->extras[j].data); #endif + if (common_fuzz_stuff(afl, ex_tmp, len + afl->extras[j].len)) { goto abandon_entry; @@ -4099,7 +4111,8 @@ skip_user_extras: afl->stage_cur_byte = i; - for (j = 0; j < MIN(afl->a_extras_cnt, (u32)USE_AUTO_EXTRAS); ++j) { + u32 min_extra_len = MIN(afl->a_extras_cnt, (u32)USE_AUTO_EXTRAS); + for (j = 0; j < min_extra_len; ++j) { /* See the comment in the earlier code; extras are sorted by size. */ @@ -4121,6 +4134,7 @@ skip_user_extras: "%s MOPT_AUTO_EXTRAS overwrite %u %u:%s", afl->queue_cur->fname, i, j, afl->a_extras[j].data); #endif + if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -4234,6 +4248,19 @@ pacemaker_fuzzing: havoc_queued = afl->queued_paths; + u32 r_max; + + r_max = 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0); + + if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) { + + /* add expensive havoc cases here, they are activated after a full + cycle without finds happened */ + + ++r_max; + + } + for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { @@ -4254,12 +4281,12 @@ pacemaker_fuzzing: for (i = 0; i < use_stacking; ++i) { - switch (select_algorithm(afl)) { + switch (select_algorithm(afl, r_max)) { case 0: /* Flip a single bit somewhere. Spooky! */ FLIP_BIT(out_buf, rand_below(afl, temp_len << 3)); - MOpt_globals.cycles_v2[STAGE_FLIP1] += 1; + MOpt_globals.cycles_v2[STAGE_FLIP1]++; #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP_BIT1"); strcat(afl->mutation, afl->m_tmp); @@ -4271,7 +4298,7 @@ pacemaker_fuzzing: temp_len_puppet = rand_below(afl, (temp_len << 3) - 1); FLIP_BIT(out_buf, temp_len_puppet); FLIP_BIT(out_buf, temp_len_puppet + 1); - MOpt_globals.cycles_v2[STAGE_FLIP2] += 1; + MOpt_globals.cycles_v2[STAGE_FLIP2]++; #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP_BIT2"); strcat(afl->mutation, afl->m_tmp); @@ -4285,7 +4312,7 @@ pacemaker_fuzzing: FLIP_BIT(out_buf, temp_len_puppet + 1); FLIP_BIT(out_buf, temp_len_puppet + 2); FLIP_BIT(out_buf, temp_len_puppet + 3); - MOpt_globals.cycles_v2[STAGE_FLIP4] += 1; + MOpt_globals.cycles_v2[STAGE_FLIP4]++; #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP_BIT4"); strcat(afl->mutation, afl->m_tmp); @@ -4295,7 +4322,7 @@ pacemaker_fuzzing: case 3: if (temp_len < 4) { break; } out_buf[rand_below(afl, temp_len)] ^= 0xFF; - MOpt_globals.cycles_v2[STAGE_FLIP8] += 1; + MOpt_globals.cycles_v2[STAGE_FLIP8]++; #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP_BIT8"); strcat(afl->mutation, afl->m_tmp); @@ -4305,7 +4332,7 @@ pacemaker_fuzzing: case 4: if (temp_len < 8) { break; } *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) ^= 0xFFFF; - MOpt_globals.cycles_v2[STAGE_FLIP16] += 1; + MOpt_globals.cycles_v2[STAGE_FLIP16]++; #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP_BIT16"); strcat(afl->mutation, afl->m_tmp); @@ -4315,7 +4342,7 @@ pacemaker_fuzzing: case 5: if (temp_len < 8) { break; } *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) ^= 0xFFFFFFFF; - MOpt_globals.cycles_v2[STAGE_FLIP32] += 1; + MOpt_globals.cycles_v2[STAGE_FLIP32]++; #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP_BIT32"); strcat(afl->mutation, afl->m_tmp); @@ -4327,7 +4354,7 @@ pacemaker_fuzzing: 1 + rand_below(afl, ARITH_MAX); out_buf[rand_below(afl, temp_len)] += 1 + rand_below(afl, ARITH_MAX); - MOpt_globals.cycles_v2[STAGE_ARITH8] += 1; + MOpt_globals.cycles_v2[STAGE_ARITH8]++; #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH+-"); strcat(afl->mutation, afl->m_tmp); @@ -4384,7 +4411,7 @@ pacemaker_fuzzing: } - MOpt_globals.cycles_v2[STAGE_ARITH16] += 1; + MOpt_globals.cycles_v2[STAGE_ARITH16]++; break; case 8: @@ -4438,7 +4465,7 @@ pacemaker_fuzzing: } - MOpt_globals.cycles_v2[STAGE_ARITH32] += 1; + MOpt_globals.cycles_v2[STAGE_ARITH32]++; break; case 9: @@ -4446,7 +4473,7 @@ pacemaker_fuzzing: if (temp_len < 4) { break; } out_buf[rand_below(afl, temp_len)] = interesting_8[rand_below(afl, sizeof(interesting_8))]; - MOpt_globals.cycles_v2[STAGE_INTEREST8] += 1; + MOpt_globals.cycles_v2[STAGE_INTEREST8]++; #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING8"); strcat(afl->mutation, afl->m_tmp); @@ -4478,7 +4505,7 @@ pacemaker_fuzzing: } - MOpt_globals.cycles_v2[STAGE_INTEREST16] += 1; + MOpt_globals.cycles_v2[STAGE_INTEREST16]++; break; case 11: @@ -4508,7 +4535,7 @@ pacemaker_fuzzing: } - MOpt_globals.cycles_v2[STAGE_INTEREST32] += 1; + MOpt_globals.cycles_v2[STAGE_INTEREST32]++; break; case 12: @@ -4518,7 +4545,7 @@ pacemaker_fuzzing: possibility of a no-op. */ out_buf[rand_below(afl, temp_len)] ^= 1 + rand_below(afl, 255); - MOpt_globals.cycles_v2[STAGE_RANDOMBYTE] += 1; + MOpt_globals.cycles_v2[STAGE_RANDOMBYTE]++; #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), " RAND8"); strcat(afl->mutation, afl->m_tmp); @@ -4541,16 +4568,16 @@ pacemaker_fuzzing: del_from = rand_below(afl, temp_len - del_len + 1); - memmove(out_buf + del_from, out_buf + del_from + del_len, - temp_len - del_from - del_len); - - temp_len -= del_len; - MOpt_globals.cycles_v2[STAGE_DELETEBYTE] += 1; #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), " DEL-%u%u", del_from, del_len); strcat(afl->mutation, afl->m_tmp); #endif + memmove(out_buf + del_from, out_buf + del_from + del_len, + temp_len - del_from - del_len); + + temp_len -= del_len; + MOpt_globals.cycles_v2[STAGE_DELETEBYTE]++; break; } @@ -4566,7 +4593,7 @@ pacemaker_fuzzing: u32 clone_from, clone_to, clone_len; u8 *new_buf; - if (actually_clone) { + if (likely(actually_clone)) { clone_len = choose_block_len(afl, temp_len); clone_from = rand_below(afl, temp_len - clone_len + 1); @@ -4617,7 +4644,7 @@ pacemaker_fuzzing: out_buf = new_buf; afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); temp_len += clone_len; - MOpt_globals.cycles_v2[STAGE_Clone75] += 1; + MOpt_globals.cycles_v2[STAGE_Clone75]++; } @@ -4637,9 +4664,9 @@ pacemaker_fuzzing: copy_from = rand_below(afl, temp_len - copy_len + 1); copy_to = rand_below(afl, temp_len - copy_len + 1); - if (rand_below(afl, 4)) { + if (likely(rand_below(afl, 4))) { - if (copy_from != copy_to) { + if (likely(copy_from != copy_to)) { #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), @@ -4666,7 +4693,7 @@ pacemaker_fuzzing: } - MOpt_globals.cycles_v2[STAGE_OverWrite75] += 1; + MOpt_globals.cycles_v2[STAGE_OverWrite75]++; break; } /* case 15 */ @@ -4721,7 +4748,7 @@ pacemaker_fuzzing: } afl->stage_cycles_puppet_v2[afl->swarm_now] - [STAGE_OverWriteExtra] += 1; + [STAGE_OverWriteExtra]++; break; @@ -4783,11 +4810,93 @@ pacemaker_fuzzing: } + default: { + + if (unlikely(afl->ready_for_splicing_count < 2)) break; + + u32 tid; + do { + + tid = rand_below(afl, afl->queued_paths); + + } while (tid == afl->current_entry || + + afl->queue_buf[tid]->len < 4); + + /* Get the testcase for splicing. */ + struct queue_entry *target = afl->queue_buf[tid]; + u32 new_len = target->len; + u8 * new_buf = queue_testcase_get(afl, target); + + if ((temp_len >= 2 && rand_below(afl, 2)) || + temp_len + HAVOC_BLK_XL >= MAX_FILE) { + + /* overwrite mode */ + + u32 copy_from, copy_to, copy_len; + + copy_len = choose_block_len(afl, new_len - 1); + if ((s32)copy_len > temp_len) copy_len = temp_len; + + copy_from = rand_below(afl, new_len - copy_len + 1); + copy_to = rand_below(afl, temp_len - copy_len + 1); + +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " SPLICE_OVERWRITE_%u_%u_%u_%s", copy_from, copy_to, + copy_len, target->fname); + strcat(afl->mutation, afl->m_tmp); +#endif + memmove(out_buf + copy_to, new_buf + copy_from, copy_len); + + } else { + + /* insert mode */ + + u32 clone_from, clone_to, clone_len; + + clone_len = choose_block_len(afl, new_len); + clone_from = rand_below(afl, new_len - clone_len + 1); + clone_to = rand_below(afl, temp_len + 1); + + u8 *temp_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), + temp_len + clone_len + 1); + if (unlikely(!temp_buf)) { PFATAL("alloc"); } + +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " SPLICE_INSERT_%u_%u_%u_%s", clone_from, clone_to, + clone_len, target->fname); + strcat(afl->mutation, afl->m_tmp); +#endif + /* Head */ + + memcpy(temp_buf, out_buf, clone_to); + + /* Inserted part */ + + memcpy(temp_buf + clone_to, new_buf + clone_from, clone_len); + + /* Tail */ + memcpy(temp_buf + clone_to + clone_len, out_buf + clone_to, + temp_len - clone_to); + + out_buf = temp_buf; + afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); + temp_len += clone_len; + + } + + afl->stage_cycles_puppet_v2[afl->swarm_now][STAGE_Splice]++; + break; + + } // end of default: + } /* switch select_algorithm() */ } /* for i=0; i < use_stacking */ - *MOpt_globals.pTime += 1; + ++*MOpt_globals.pTime; u64 temp_total_found = afl->queued_paths + afl->unique_crashes; @@ -5138,7 +5247,7 @@ u8 pilot_fuzzing(afl_state_t *afl) { void pso_updating(afl_state_t *afl) { - afl->g_now += 1; + afl->g_now++; if (afl->g_now > afl->g_max) { afl->g_now = 0; } afl->w_now = (afl->w_init - afl->w_end) * (afl->g_max - afl->g_now) / (afl->g_max) + -- cgit v1.2.3 From 350c3b323a59c99891635a233c3f82f83653947c Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Mon, 2 Nov 2020 21:17:37 +0100 Subject: fix for #562 --- src/afl-tmin.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/afl-tmin.c b/src/afl-tmin.c index efc12d4f..06037d61 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -656,6 +656,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) { unlink(out_file); + fsrv->out_file = out_file; fsrv->out_fd = open(out_file, O_RDWR | O_CREAT | O_EXCL, 0600); if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", out_file); } -- cgit v1.2.3 From d795ec0451bfb6f93485c4ec6436ae1af3840070 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 3 Nov 2020 13:41:06 +0100 Subject: added better error handling to forkserver fd --- src/afl-forkserver.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index d23cf6eb..714be24e 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -983,10 +983,13 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { if (fd < 0) { PFATAL("Unable to create '%s'", fsrv->out_file); } - } else if (unlikely(!fd)) { + } else if (unlikely(fd <= 0)) { - // We should never have stdin as fd here, 0 is likely unset. - FATAL("Nowhere to write output to (neither out_fd nor out_file set)"); + // We should have a (non-stdin) fd at this point, else we got a problem. + FATAL( + "Nowhere to write output to (neither out_fd nor out_file set (fd is " + "%d))", + fd); } else { -- cgit v1.2.3 From 7ed0bfb6f51ff9c331c09315d72baad7b14259e5 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 3 Nov 2020 15:09:57 +0100 Subject: copy fsrv: copy out_file ptr --- src/afl-forkserver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 714be24e..b717c1ad 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -114,7 +114,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->child_pid = -1; fsrv_to->use_fauxsrv = 0; fsrv_to->last_run_timed_out = 0; - fsrv_to->out_file = NULL; + fsrv_to->out_file = from->out_file; fsrv_to->init_child_func = fsrv_exec_child; // Note: do not copy ->add_extra_func -- cgit v1.2.3 From 8bccf5655354540db5f6f208731d261dcfe05e2d Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 3 Nov 2020 15:13:04 +0100 Subject: fsrv copy: out_fd = -1 --- src/afl-forkserver.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index b717c1ad..313aa363 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -99,14 +99,13 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) { void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->use_stdin = from->use_stdin; - fsrv_to->out_fd = from->out_fd; fsrv_to->dev_null_fd = from->dev_null_fd; fsrv_to->exec_tmout = from->exec_tmout; fsrv_to->init_tmout = from->init_tmout; fsrv_to->mem_limit = from->mem_limit; fsrv_to->map_size = from->map_size; fsrv_to->support_shmem_fuzz = from->support_shmem_fuzz; - + fsrv_to->out_file = from->out_file; fsrv_to->dev_urandom_fd = from->dev_urandom_fd; // These are forkserver specific. @@ -114,7 +113,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->child_pid = -1; fsrv_to->use_fauxsrv = 0; fsrv_to->last_run_timed_out = 0; - fsrv_to->out_file = from->out_file; + fsrv_to->out_fd = -1; fsrv_to->init_child_func = fsrv_exec_child; // Note: do not copy ->add_extra_func -- cgit v1.2.3 From 245f511a1d3432927ba101e270d7c6e4157e8e63 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 3 Nov 2020 15:15:58 +0100 Subject: fsrv copy: out_fd = 0 on stdin --- src/afl-forkserver.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 313aa363..d294f7fc 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -113,7 +113,16 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->child_pid = -1; fsrv_to->use_fauxsrv = 0; fsrv_to->last_run_timed_out = 0; - fsrv_to->out_fd = -1; + + if (fsrv_to->use_stdin) { + + fsrv_to->out_fd = 0; + + } else { + + fsrv_to->out_fd = -1; + + } fsrv_to->init_child_func = fsrv_exec_child; // Note: do not copy ->add_extra_func -- cgit v1.2.3 From 7b4d1c408909dd27d81967eced963f3b661511c8 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 3 Nov 2020 15:52:19 +0100 Subject: revert out_fd copy --- src/afl-forkserver.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index d294f7fc..a8c486b6 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -107,6 +107,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->support_shmem_fuzz = from->support_shmem_fuzz; fsrv_to->out_file = from->out_file; fsrv_to->dev_urandom_fd = from->dev_urandom_fd; + fsrv_to->out_fd = from->out_fd; // not sure this is a good idea // These are forkserver specific. fsrv_to->out_dir_fd = -1; @@ -114,16 +115,6 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->use_fauxsrv = 0; fsrv_to->last_run_timed_out = 0; - if (fsrv_to->use_stdin) { - - fsrv_to->out_fd = 0; - - } else { - - fsrv_to->out_fd = -1; - - } - fsrv_to->init_child_func = fsrv_exec_child; // Note: do not copy ->add_extra_func -- cgit v1.2.3 From 3cfc0174f7fac85f232052dffdb1eb83ea3ef24d Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 3 Nov 2020 16:00:29 +0100 Subject: fix -N for forkserver --- src/afl-forkserver.c | 3 ++- src/afl-fuzz-run.c | 4 ++-- src/afl-fuzz.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index a8c486b6..45be2abd 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -108,6 +108,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->out_file = from->out_file; fsrv_to->dev_urandom_fd = from->dev_urandom_fd; fsrv_to->out_fd = from->out_fd; // not sure this is a good idea + fsrv_to->no_unlink = from->no_unlink; // These are forkserver specific. fsrv_to->out_dir_fd = -1; @@ -969,7 +970,7 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { if (!fsrv->use_stdin && fsrv->out_file) { - if (fsrv->no_unlink) { + if (unlikely(fsrv->no_unlink)) { fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_TRUNC, 0600); diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index fb259b5d..e969994d 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -243,7 +243,7 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at, } else if (afl->fsrv.out_file) { - if (afl->no_unlink) { + if (unlikely(afl->no_unlink)) { fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_TRUNC, 0600); @@ -824,7 +824,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { s32 fd; - if (afl->no_unlink) { + if (unlikely(afl->no_unlink)) { fd = open(q->fname, O_WRONLY | O_CREAT | O_TRUNC, 0600); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 575e6b74..67cde96a 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -656,7 +656,7 @@ int main(int argc, char **argv_orig, char **envp) { case 'N': /* Unicorn mode */ if (afl->no_unlink) { FATAL("Multiple -N options not supported"); } - afl->no_unlink = 1; + afl->fsrv.no_unlink = afl->no_unlink = 1; break; -- cgit v1.2.3 From 6abe4d124ec23d3ab9fc5f7bec4ffa1c0a1eba22 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 5 Nov 2020 08:53:16 +0100 Subject: require llvm 10.0.1+ for enhanced pcguard, correct 1MB checks --- src/afl-cc.c | 8 ++++---- src/afl-fuzz.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 1a7a837f..46468dda 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -501,7 +501,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (instrument_mode == INSTRUMENT_PCGUARD) { -#if LLVM_MAJOR >= 10 +#if LLVM_MAJOR >= 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; @@ -511,7 +511,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { #if LLVM_MAJOR >= 4 if (!be_quiet) SAYF( - "Using unoptimized trace-pc-guard, upgrade to llvm 10+ for " + "Using unoptimized trace-pc-guard, upgrade to llvm 10.0.1+ for " "enhanced version.\n"); cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; #else @@ -715,14 +715,14 @@ static void edit_params(u32 argc, char **argv, char **envp) { "int __afl_sharedmem_fuzzing = 1;" "extern unsigned int *__afl_fuzz_len;" "extern unsigned char *__afl_fuzz_ptr;" - "unsigned char __afl_fuzz_alt[1024000];" + "unsigned char __afl_fuzz_alt[1048576];" "unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt;"; cc_params[cc_par_cnt++] = "-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : " "__afl_fuzz_alt_ptr)"; cc_params[cc_par_cnt++] = "-D__AFL_FUZZ_TESTCASE_LEN=(__afl_fuzz_ptr ? *__afl_fuzz_len : " - "(*__afl_fuzz_len = read(0, __afl_fuzz_alt_ptr, 1024000)) == 0xffffffff " + "(*__afl_fuzz_len = read(0, __afl_fuzz_alt_ptr, 1048576)) == 0xffffffff " "? 0 : *__afl_fuzz_len)"; cc_params[cc_par_cnt++] = diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 67cde96a..269ce1bf 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1064,13 +1064,13 @@ int main(int argc, char **argv_orig, char **envp) { } else if (afl->q_testcase_max_cache_size < 2 * MAX_FILE) { FATAL("AFL_TESTCACHE_SIZE must be set to %u or more, or 0 to disable", - (2 * MAX_FILE) % 1024000 == 0 ? (2 * MAX_FILE) / 1048576 + (2 * MAX_FILE) % 1048576 == 0 ? (2 * MAX_FILE) / 1048576 : 1 + ((2 * MAX_FILE) / 1048576)); } else { OKF("Enabled testcache with %llu MB", - afl->q_testcase_max_cache_size / 1024000); + afl->q_testcase_max_cache_size / 1048576); } -- cgit v1.2.3 From a728e8f9a5518017cde12bdb6ba795a6bcb47b0a Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 6 Nov 2020 16:42:02 +0100 Subject: better scriptable output from introspection --- src/afl-fuzz-one.c | 191 +++++++++++++++++++++++++---------------------------- 1 file changed, 90 insertions(+), 101 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index e4016773..91bbced6 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -613,7 +613,7 @@ u8 fuzz_one_original(afl_state_t *afl) { FLIP_BIT(out_buf, afl->stage_cur); #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT1 %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT1-%u", afl->queue_cur->fname, afl->stage_cur); #endif @@ -727,7 +727,7 @@ u8 fuzz_one_original(afl_state_t *afl) { FLIP_BIT(out_buf, afl->stage_cur + 1); #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT2 %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT2-%u", afl->queue_cur->fname, afl->stage_cur); #endif @@ -761,7 +761,7 @@ u8 fuzz_one_original(afl_state_t *afl) { FLIP_BIT(out_buf, afl->stage_cur + 3); #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT4 %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT4-%u", afl->queue_cur->fname, afl->stage_cur); #endif @@ -821,7 +821,7 @@ u8 fuzz_one_original(afl_state_t *afl) { out_buf[afl->stage_cur] ^= 0xFF; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT8 %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT8-%u", afl->queue_cur->fname, afl->stage_cur); #endif @@ -913,7 +913,7 @@ u8 fuzz_one_original(afl_state_t *afl) { *(u16 *)(out_buf + i) ^= 0xFFFF; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT16 %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT16-%u", afl->queue_cur->fname, afl->stage_cur); #endif @@ -956,7 +956,7 @@ u8 fuzz_one_original(afl_state_t *afl) { *(u32 *)(out_buf + i) ^= 0xFFFFFFFF; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT32 %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s FLIP_BIT32-%u", afl->queue_cur->fname, afl->stage_cur); #endif @@ -1019,7 +1019,7 @@ skip_bitflip: out_buf[i] = orig + j; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH8+ %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH8+-%u-%u", afl->queue_cur->fname, i, j); #endif @@ -1040,7 +1040,7 @@ skip_bitflip: out_buf[i] = orig - j; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH8- %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH8--%u-%u", afl->queue_cur->fname, i, j); #endif @@ -1109,7 +1109,7 @@ skip_bitflip: *(u16 *)(out_buf + i) = orig + j; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH16+ %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH16+-%u-%u", afl->queue_cur->fname, i, j); #endif @@ -1128,7 +1128,7 @@ skip_bitflip: *(u16 *)(out_buf + i) = orig - j; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH16- %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH16--%u-%u", afl->queue_cur->fname, i, j); #endif @@ -1151,7 +1151,7 @@ skip_bitflip: *(u16 *)(out_buf + i) = SWAP16(SWAP16(orig) + j); #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH16+BE %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH16+BE-%u-%u", afl->queue_cur->fname, i, j); #endif @@ -1170,7 +1170,7 @@ skip_bitflip: *(u16 *)(out_buf + i) = SWAP16(SWAP16(orig) - j); #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH16-BE %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH16_BE-%u-%u", afl->queue_cur->fname, i, j); #endif @@ -1238,7 +1238,7 @@ skip_bitflip: *(u32 *)(out_buf + i) = orig + j; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH32+ %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH32+-%u-%u", afl->queue_cur->fname, i, j); #endif @@ -1257,7 +1257,7 @@ skip_bitflip: *(u32 *)(out_buf + i) = orig - j; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH32- %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH32_-%u-%u", afl->queue_cur->fname, i, j); #endif @@ -1280,7 +1280,7 @@ skip_bitflip: *(u32 *)(out_buf + i) = SWAP32(SWAP32(orig) + j); #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH32+BE %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH32+BE-%u-%u", afl->queue_cur->fname, i, j); #endif @@ -1299,7 +1299,7 @@ skip_bitflip: *(u32 *)(out_buf + i) = SWAP32(SWAP32(orig) - j); #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH32-BE %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s ARITH32_BE-%u-%u", afl->queue_cur->fname, i, j); #endif @@ -1371,7 +1371,7 @@ skip_arith: out_buf[i] = interesting_8[j]; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s INTERESTING8 %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s INTERESTING8_%u_%u", afl->queue_cur->fname, i, j); #endif @@ -1431,7 +1431,7 @@ skip_arith: *(u16 *)(out_buf + i) = interesting_16[j]; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s INTERESTING16 %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s INTERESTING16_%u_%u", afl->queue_cur->fname, i, j); #endif @@ -1453,7 +1453,7 @@ skip_arith: #ifdef INTROSPECTION snprintf(afl->mutation, sizeof(afl->mutation), - "%s INTERESTING16BE %u %u", afl->queue_cur->fname, i, j); + "%s INTERESTING16BE_%u_%u", afl->queue_cur->fname, i, j); #endif *(u16 *)(out_buf + i) = SWAP16(interesting_16[j]); @@ -1520,7 +1520,7 @@ skip_arith: *(u32 *)(out_buf + i) = interesting_32[j]; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s INTERESTING32 %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s INTERESTING32_%u_%u", afl->queue_cur->fname, i, j); #endif @@ -1542,7 +1542,7 @@ skip_arith: #ifdef INTROSPECTION snprintf(afl->mutation, sizeof(afl->mutation), - "%s INTERESTING32BE %u %u", afl->queue_cur->fname, i, j); + "%s INTERESTING32BE_%u_%u", afl->queue_cur->fname, i, j); #endif *(u32 *)(out_buf + i) = SWAP32(interesting_32[j]); @@ -1620,8 +1620,7 @@ skip_interest: #ifdef INTROSPECTION snprintf(afl->mutation, sizeof(afl->mutation), - "%s EXTRAS overwrite %u %u:%s", afl->queue_cur->fname, i, j, - afl->extras[j].data); + "%s EXTRAS_overwrite-%u-%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -1672,9 +1671,8 @@ skip_interest: memcpy(ex_tmp + i + afl->extras[j].len, out_buf + i, len - i); #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), - "%s EXTRAS insert %u %u:%s", afl->queue_cur->fname, i, j, - afl->extras[j].data); + snprintf(afl->mutation, sizeof(afl->mutation), "%s EXTRAS_insert-%u-%u", + afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, ex_tmp, len + afl->extras[j].len)) { @@ -1736,8 +1734,7 @@ skip_user_extras: #ifdef INTROSPECTION snprintf(afl->mutation, sizeof(afl->mutation), - "%s AUTO_EXTRAS overwrite %u %u:%s", afl->queue_cur->fname, i, j, - afl->a_extras[j].data); + "%s AUTO_EXTRAS_overwrite-%u-%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -1844,7 +1841,7 @@ custom_mutator_stage: if (mutated_size > 0) { #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s CUSTOM %s", + snprintf(afl->mutation, sizeof(afl->mutation), "%s CUSTOM-%s", afl->queue_cur->fname, target != NULL ? (char *)target->fname : "none"); #endif @@ -1999,7 +1996,7 @@ havoc_stage: afl->stage_cur_val = use_stacking; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s HAVOC %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s HAVOC-%u", afl->queue_cur->fname, use_stacking); #endif @@ -2126,7 +2123,7 @@ havoc_stage: /* Randomly subtract from byte. */ #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH8-"); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH8_"); strcat(afl->mutation, afl->m_tmp); #endif out_buf[rand_below(afl, temp_len)] -= 1 + rand_below(afl, ARITH_MAX); @@ -2154,7 +2151,7 @@ havoc_stage: u32 pos = rand_below(afl, temp_len - 1); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16-_%u", pos); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16_-%u", pos); strcat(afl->mutation, afl->m_tmp); #endif *(u16 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); @@ -2165,7 +2162,7 @@ havoc_stage: u16 num = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16-BE_%u_%u", pos, + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16_BE-%u_%u", pos, num); strcat(afl->mutation, afl->m_tmp); #endif @@ -2187,7 +2184,7 @@ havoc_stage: u32 pos = rand_below(afl, temp_len - 1); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+_%u", pos); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+-%u", pos); strcat(afl->mutation, afl->m_tmp); #endif *(u16 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); @@ -2198,7 +2195,7 @@ havoc_stage: u16 num = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+BE_%u_%u", pos, + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+BE-%u_%u", pos, num); strcat(afl->mutation, afl->m_tmp); #endif @@ -2220,7 +2217,7 @@ havoc_stage: u32 pos = rand_below(afl, temp_len - 3); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32-_%u", pos); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32_-%u", pos); strcat(afl->mutation, afl->m_tmp); #endif *(u32 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); @@ -2231,7 +2228,7 @@ havoc_stage: u32 num = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32-BE_%u_%u", pos, + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32_BE-%u-%u", pos, num); strcat(afl->mutation, afl->m_tmp); #endif @@ -2253,7 +2250,7 @@ havoc_stage: u32 pos = rand_below(afl, temp_len - 3); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+_%u", pos); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+-%u", pos); strcat(afl->mutation, afl->m_tmp); #endif *(u32 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); @@ -2264,7 +2261,7 @@ havoc_stage: u32 num = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+BE_%u_%u", pos, + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+BE-%u-%u", pos, num); strcat(afl->mutation, afl->m_tmp); #endif @@ -2305,7 +2302,7 @@ havoc_stage: del_from = rand_below(afl, temp_len - del_len + 1); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " DEL_%u_%u", del_from, + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " DEL-%u-%u", del_from, del_len); strcat(afl->mutation, afl->m_tmp); #endif @@ -2343,7 +2340,7 @@ havoc_stage: clone_to = rand_below(afl, temp_len); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE_%s_%u_%u_%u", + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE-%s-%u-%u-%u", actually_clone ? "clone" : "insert", clone_from, clone_to, clone_len); strcat(afl->mutation, afl->m_tmp); @@ -2403,7 +2400,7 @@ havoc_stage: #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " OVERWRITE_COPY_%u_%u_%u", copy_from, copy_to, + " OVERWRITE_COPY-%u-%u-%u", copy_from, copy_to, copy_len); strcat(afl->mutation, afl->m_tmp); #endif @@ -2415,7 +2412,7 @@ havoc_stage: #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " OVERWRITE_FIXED_%u_%u_%u", copy_from, copy_to, copy_len); + " OVERWRITE_FIXED-%u-%u-%u", copy_from, copy_to, copy_len); strcat(afl->mutation, afl->m_tmp); #endif memset(out_buf + copy_to, @@ -2454,8 +2451,7 @@ havoc_stage: u32 insert_at = rand_below(afl, temp_len - extra_len + 1); #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " AUTO_EXTRA_OVERWRITE_%u_%u_%s", insert_at, extra_len, - afl->a_extras[use_extra].data); + " AUTO_EXTRA_OVERWRITE-%u-%u", insert_at, extra_len); strcat(afl->mutation, afl->m_tmp); #endif memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, @@ -2473,8 +2469,7 @@ havoc_stage: u32 insert_at = rand_below(afl, temp_len - extra_len + 1); #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " EXTRA_OVERWRITE_%u_%u_%s", insert_at, extra_len, - afl->a_extras[use_extra].data); + " EXTRA_OVERWRITE-%u-%u", insert_at, extra_len); strcat(afl->mutation, afl->m_tmp); #endif memcpy(out_buf + insert_at, afl->extras[use_extra].data, @@ -2501,8 +2496,7 @@ havoc_stage: ptr = afl->a_extras[use_extra].data; #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " AUTO_EXTRA_INSERT_%u_%u_%s", insert_at, extra_len, - ptr); + " AUTO_EXTRA_INSERT-%u-%u", insert_at, extra_len); strcat(afl->mutation, afl->m_tmp); #endif @@ -2512,8 +2506,8 @@ havoc_stage: extra_len = afl->extras[use_extra].len; ptr = afl->extras[use_extra].data; #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " EXTRA_INSERT_%u_%u_%s", insert_at, extra_len, ptr); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " EXTRA_INSERT-%u-%u", + insert_at, extra_len); strcat(afl->mutation, afl->m_tmp); #endif @@ -2578,7 +2572,7 @@ havoc_stage: #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " SPLICE_OVERWRITE_%u_%u_%u_%s", copy_from, copy_to, + " SPLICE_OVERWRITE-%u-%u-%u-%s", copy_from, copy_to, copy_len, target->fname); strcat(afl->mutation, afl->m_tmp); #endif @@ -2600,7 +2594,7 @@ havoc_stage: #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " SPLICE_INSERT_%u_%u_%u_%s", clone_from, clone_to, + " SPLICE_INSERT-%u-%u-%u-%s", clone_from, clone_to, clone_len, target->fname); strcat(afl->mutation, afl->m_tmp); #endif @@ -3029,7 +3023,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { FLIP_BIT(out_buf, afl->stage_cur); #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT1 %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT1-%u", afl->queue_cur->fname, afl->stage_cur); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -3142,7 +3136,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { FLIP_BIT(out_buf, afl->stage_cur + 1); #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT2 %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT2-%u", afl->queue_cur->fname, afl->stage_cur); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -3175,7 +3169,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { FLIP_BIT(out_buf, afl->stage_cur + 3); #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT4 %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT4-%u", afl->queue_cur->fname, afl->stage_cur); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -3234,7 +3228,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { out_buf[afl->stage_cur] ^= 0xFF; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT8 %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT8-%u", afl->queue_cur->fname, afl->stage_cur); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -3325,7 +3319,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { *(u16 *)(out_buf + i) ^= 0xFFFF; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT16 %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT16-%u", afl->queue_cur->fname, afl->stage_cur); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -3367,7 +3361,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { *(u32 *)(out_buf + i) ^= 0xFFFFFFFF; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT32 %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_FLIP_BIT32-%u", afl->queue_cur->fname, afl->stage_cur); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -3429,7 +3423,7 @@ skip_bitflip: out_buf[i] = orig + j; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH8+ %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH8+-%u-%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -3449,7 +3443,7 @@ skip_bitflip: out_buf[i] = orig - j; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH8- %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH8_-%u-%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -3517,7 +3511,7 @@ skip_bitflip: *(u16 *)(out_buf + i) = orig + j; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH16+ %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH16+-%u-%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -3535,7 +3529,7 @@ skip_bitflip: *(u16 *)(out_buf + i) = orig - j; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH16- %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH16_-%u-%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -3558,7 +3552,7 @@ skip_bitflip: #ifdef INTROSPECTION snprintf(afl->mutation, sizeof(afl->mutation), - "%s MOPT_ARITH16+BE %u %u", afl->queue_cur->fname, i, j); + "%s MOPT_ARITH16+BE-%u-%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3576,7 +3570,7 @@ skip_bitflip: #ifdef INTROSPECTION snprintf(afl->mutation, sizeof(afl->mutation), - "%s MOPT_ARITH16-BE %u %u", afl->queue_cur->fname, i, j); + "%s MOPT_ARITH16_BE+%u+%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3642,7 +3636,7 @@ skip_bitflip: *(u32 *)(out_buf + i) = orig + j; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH32+ %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH32+-%u-%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -3660,7 +3654,7 @@ skip_bitflip: *(u32 *)(out_buf + i) = orig - j; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH32- %u %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_ARITH32_-%u-%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -3683,7 +3677,7 @@ skip_bitflip: #ifdef INTROSPECTION snprintf(afl->mutation, sizeof(afl->mutation), - "%s MOPT_ARITH32+BE %u %u", afl->queue_cur->fname, i, j); + "%s MOPT_ARITH32+BE-%u-%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3701,7 +3695,7 @@ skip_bitflip: #ifdef INTROSPECTION snprintf(afl->mutation, sizeof(afl->mutation), - "%s MOPT_ARITH32-BE %u %u", afl->queue_cur->fname, i, j); + "%s MOPT_ARITH32_BE-%u-%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3772,7 +3766,7 @@ skip_arith: #ifdef INTROSPECTION snprintf(afl->mutation, sizeof(afl->mutation), - "%s MOPT_INTERESTING8 %u %u", afl->queue_cur->fname, i, j); + "%s MOPT_INTERESTING8-%u-%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -3831,7 +3825,7 @@ skip_arith: #ifdef INTROSPECTION snprintf(afl->mutation, sizeof(afl->mutation), - "%s MOPT_INTERESTING16 %u %u", afl->queue_cur->fname, i, j); + "%s MOPT_INTERESTING16-%u-%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3851,7 +3845,7 @@ skip_arith: #ifdef INTROSPECTION snprintf(afl->mutation, sizeof(afl->mutation), - "%s MOPT_INTERESTING16BE %u %u", afl->queue_cur->fname, i, j); + "%s MOPT_INTERESTING16BE-%u-%u", afl->queue_cur->fname, i, j); #endif *(u16 *)(out_buf + i) = SWAP16(interesting_16[j]); if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -3918,7 +3912,7 @@ skip_arith: #ifdef INTROSPECTION snprintf(afl->mutation, sizeof(afl->mutation), - "%s MOPT_INTERESTING32 %u %u", afl->queue_cur->fname, i, j); + "%s MOPT_INTERESTING32-%u-%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } ++afl->stage_cur; @@ -3938,7 +3932,7 @@ skip_arith: #ifdef INTROSPECTION snprintf(afl->mutation, sizeof(afl->mutation), - "%s MOPT_INTERESTING32BE %u %u", afl->queue_cur->fname, i, j); + "%s MOPT_INTERESTING32BE-%u-%u", afl->queue_cur->fname, i, j); #endif *(u32 *)(out_buf + i) = SWAP32(interesting_32[j]); if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -4015,8 +4009,7 @@ skip_interest: #ifdef INTROSPECTION snprintf(afl->mutation, sizeof(afl->mutation), - "%s MOPT_EXTRAS overwrite %u %u:%s", afl->queue_cur->fname, i, j, - afl->extras[j].data); + "%s MOPT_EXTRAS_overwrite-%u-%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -4068,8 +4061,7 @@ skip_interest: #ifdef INTROSPECTION snprintf(afl->mutation, sizeof(afl->mutation), - "%s MOPT_EXTRAS insert %u %u:%s", afl->queue_cur->fname, i, j, - afl->extras[j].data); + "%s MOPT_EXTRAS_insert-%u-%u", afl->queue_cur->fname, i, j); #endif if (common_fuzz_stuff(afl, ex_tmp, len + afl->extras[j].len)) { @@ -4131,8 +4123,8 @@ skip_user_extras: #ifdef INTROSPECTION snprintf(afl->mutation, sizeof(afl->mutation), - "%s MOPT_AUTO_EXTRAS overwrite %u %u:%s", afl->queue_cur->fname, - i, j, afl->a_extras[j].data); + "%s MOPT_AUTO_EXTRAS_overwrite-%u-%u", afl->queue_cur->fname, i, + j); #endif if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; } @@ -4275,7 +4267,7 @@ pacemaker_fuzzing: } #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_HAVOC %u", + snprintf(afl->mutation, sizeof(afl->mutation), "%s MOPT_HAVOC-%u", afl->queue_cur->fname, use_stacking); #endif @@ -4356,7 +4348,7 @@ pacemaker_fuzzing: 1 + rand_below(afl, ARITH_MAX); MOpt_globals.cycles_v2[STAGE_ARITH8]++; #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH+-"); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH8"); strcat(afl->mutation, afl->m_tmp); #endif break; @@ -4392,7 +4384,7 @@ pacemaker_fuzzing: u32 pos = rand_below(afl, temp_len - 1); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+%u", pos); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+-%u", pos); strcat(afl->mutation, afl->m_tmp); #endif *(u16 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); @@ -4402,7 +4394,7 @@ pacemaker_fuzzing: u32 pos = rand_below(afl, temp_len - 1); u16 num = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16BE+%u-%u", + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16BE+-%u-%u", pos, num); strcat(afl->mutation, afl->m_tmp); #endif @@ -4421,7 +4413,7 @@ pacemaker_fuzzing: u32 pos = rand_below(afl, temp_len - 3); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32-%u", pos); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32_-%u", pos); strcat(afl->mutation, afl->m_tmp); #endif *(u32 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); @@ -4431,7 +4423,7 @@ pacemaker_fuzzing: u32 pos = rand_below(afl, temp_len - 3); u32 num = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32BE-%u-%u", + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32BE_-%u-%u", pos, num); strcat(afl->mutation, afl->m_tmp); #endif @@ -4446,7 +4438,7 @@ pacemaker_fuzzing: u32 pos = rand_below(afl, temp_len - 3); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+%u", pos); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+-%u", pos); strcat(afl->mutation, afl->m_tmp); #endif *(u32 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); @@ -4456,7 +4448,7 @@ pacemaker_fuzzing: u32 pos = rand_below(afl, temp_len - 3); u32 num = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32BE+%u-%u", + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32BE+-%u-%u", pos, num); strcat(afl->mutation, afl->m_tmp); #endif @@ -4608,7 +4600,7 @@ pacemaker_fuzzing: clone_to = rand_below(afl, temp_len); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE_%s_%u_%u_%u", + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE_%s-%u-%u-%u", actually_clone ? "clone" : "insert", clone_from, clone_to, clone_len); strcat(afl->mutation, afl->m_tmp); @@ -4670,7 +4662,7 @@ pacemaker_fuzzing: #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " OVERWRITE_COPY_%u_%u_%u", copy_from, copy_to, + " OVERWRITE_COPY-%u-%u-%u", copy_from, copy_to, copy_len); strcat(afl->mutation, afl->m_tmp); #endif @@ -4682,7 +4674,7 @@ pacemaker_fuzzing: #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " OVERWRITE_FIXED_%u_%u_%u", copy_from, copy_to, + " OVERWRITE_FIXED-%u-%u-%u", copy_from, copy_to, copy_len); strcat(afl->mutation, afl->m_tmp); #endif @@ -4719,8 +4711,7 @@ pacemaker_fuzzing: u32 insert_at = rand_below(afl, temp_len - extra_len + 1); #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " AUTO_EXTRA_OVERWRITE_%u_%u_%s", insert_at, extra_len, - afl->a_extras[use_extra].data); + " AUTO_EXTRA_OVERWRITE-%u-%u", insert_at, extra_len); strcat(afl->mutation, afl->m_tmp); #endif memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, @@ -4738,8 +4729,7 @@ pacemaker_fuzzing: u32 insert_at = rand_below(afl, temp_len - extra_len + 1); #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " EXTRA_OVERWRITE_%u_%u_%s", insert_at, extra_len, - afl->a_extras[use_extra].data); + " EXTRA_OVERWRITE-%u-%u", insert_at, extra_len); strcat(afl->mutation, afl->m_tmp); #endif memcpy(out_buf + insert_at, afl->extras[use_extra].data, @@ -4773,8 +4763,7 @@ pacemaker_fuzzing: ptr = afl->a_extras[use_extra].data; #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " AUTO_EXTRA_INSERT_%u_%u_%s", insert_at, extra_len, - ptr); + " AUTO_EXTRA_INSERT-%u-%u", insert_at, extra_len); strcat(afl->mutation, afl->m_tmp); #endif @@ -4784,8 +4773,8 @@ pacemaker_fuzzing: extra_len = afl->extras[use_extra].len; ptr = afl->extras[use_extra].data; #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " EXTRA_INSERT_%u_%u_%s", insert_at, extra_len, ptr); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " EXTRA_INSERT-%u-%u", + insert_at, extra_len); strcat(afl->mutation, afl->m_tmp); #endif @@ -4843,7 +4832,7 @@ pacemaker_fuzzing: #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " SPLICE_OVERWRITE_%u_%u_%u_%s", copy_from, copy_to, + " SPLICE_OVERWRITE-%u-%u-%u-%s", copy_from, copy_to, copy_len, target->fname); strcat(afl->mutation, afl->m_tmp); #endif @@ -4865,7 +4854,7 @@ pacemaker_fuzzing: #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " SPLICE_INSERT_%u_%u_%u_%s", clone_from, clone_to, + " SPLICE_INSERT-%u-%u-%u-%s", clone_from, clone_to, clone_len, target->fname); strcat(afl->mutation, afl->m_tmp); #endif -- cgit v1.2.3 From 585ba4c1dda6d8706db122e15718b867fd5489cd Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 8 Nov 2020 16:33:25 +0100 Subject: fix for llvm 10.0.0 --- src/afl-cc.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 46468dda..a1c1d676 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -38,6 +38,12 @@ #if !defined(LLVM_MAJOR) #define LLVM_MAJOR 0 #endif +#if (LLVM_MINOR - 0 == 0) + #undef LLVM_MINOR +#endif +#if !defined(LLVM_MINOR) + #define LLVM_MINOR 0 +#endif static u8 * obj_path; /* Path to runtime libraries */ static u8 **cc_params; /* Parameters passed to the real CC */ -- cgit v1.2.3 From 82d1c3e18dd1b90fa15f7c056f94dc1a06ee345d Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 8 Nov 2020 17:08:30 +0100 Subject: fix wrong llvm version comparison --- src/afl-cc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index a1c1d676..771a58f5 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -507,7 +507,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (instrument_mode == INSTRUMENT_PCGUARD) { -#if LLVM_MAJOR >= 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) +#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; -- cgit v1.2.3 From 8e1047f5efaece663bba9b8ef86d181198db5101 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 10 Nov 2020 14:08:21 +0100 Subject: support custom mutator introspection --- src/afl-fuzz-bitmap.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++--- src/afl-fuzz-mutators.c | 7 +++++ src/afl-fuzz-one.c | 8 +++++ src/afl-fuzz-python.c | 33 ++++++++++++++++++++ 4 files changed, 125 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 735420c3..132499d6 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -588,8 +588,32 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { add_to_queue(afl, queue_fn, len, 0); #ifdef INTROSPECTION - fprintf(afl->introspection_file, "QUEUE %s = %s\n", afl->mutation, - afl->queue_top->fname); + if (afl->mutation[0] != 0) { + + fprintf(afl->introspection_file, "QUEUE %s = %s\n", afl->mutation, + afl->queue_top->fname); + + } else if (afl->custom_mutators_count && afl->current_custom_fuzz) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (afl->current_custom_fuzz == el && el->afl_custom_introspection) { + + const char *ptr = el->afl_custom_introspection(el->data); + + if (ptr != NULL && *ptr != 0) { + + fprintf(afl->introspection_file, "QUEUE CUSTOM %s = %s\n", ptr, + afl->queue_top->fname); + + } + + } + + }); + + } + #endif if (hnb == 2) { @@ -665,7 +689,32 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { ++afl->unique_tmouts; #ifdef INTROSPECTION - fprintf(afl->introspection_file, "UNIQUE_TIMEOUT %s\n", afl->mutation); + if (afl->mutation[0] != 0) { + + fprintf(afl->introspection_file, "UNIQUE_TIMEOUT %s\n", afl->mutation); + + } else if (afl->custom_mutators_count && afl->current_custom_fuzz) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (afl->current_custom_fuzz == el && el->afl_custom_introspection) { + + const char *ptr = el->afl_custom_introspection(el->data); + + if (ptr != NULL && *ptr != 0) { + + fprintf(afl->introspection_file, + "UNIQUE_TIMEOUT CUSTOM %s = %s\n", ptr, + afl->queue_top->fname); + + } + + } + + }); + + } + #endif /* Before saving, we make sure that it's a genuine hang by re-running @@ -751,7 +800,31 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { ++afl->unique_crashes; #ifdef INTROSPECTION - fprintf(afl->introspection_file, "UNIQUE_CRASH %s\n", afl->mutation); + if (afl->mutation[0] != 0) { + + fprintf(afl->introspection_file, "UNIQUE_CRASH %s\n", afl->mutation); + + } else if (afl->custom_mutators_count && afl->current_custom_fuzz) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (afl->current_custom_fuzz == el && el->afl_custom_introspection) { + + const char *ptr = el->afl_custom_introspection(el->data); + + if (ptr != NULL && *ptr != 0) { + + fprintf(afl->introspection_file, "UNIQUE_CRASH CUSTOM %s = %s\n", + ptr, afl->queue_top->fname); + + } + + } + + }); + + } + #endif if (unlikely(afl->infoexec)) { diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index c4d7233c..1d14f657 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -166,6 +166,13 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { } + /* "afl_custom_introspection", optional */ +#ifdef INTROSPECTION + mutator->afl_custom_introspection = dlsym(dh, "afl_custom_introspection"); + if (!mutator->afl_custom_introspection) + ACTF("optional symbol 'afl_custom_introspection' not found."); +#endif + /* "afl_custom_fuzz_count", optional */ mutator->afl_custom_fuzz_count = dlsym(dh, "afl_custom_fuzz_count"); if (!mutator->afl_custom_fuzz_count) diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 91bbced6..64365ebb 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1780,10 +1780,16 @@ custom_mutator_stage: orig_hit_cnt = afl->queued_paths + afl->unique_crashes; +#ifdef INTROSPECTION + afl->mutation[0] = 0; +#endif + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { if (el->afl_custom_fuzz) { + afl->current_custom_fuzz = el; + if (el->afl_custom_fuzz_count) afl->stage_max = el->afl_custom_fuzz_count(el->data, out_buf, len); else @@ -1889,6 +1895,8 @@ custom_mutator_stage: }); + afl->current_custom_fuzz = NULL; + if (!has_custom_fuzz) goto havoc_stage; new_hit_cnt = afl->queued_paths + afl->unique_crashes; diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index adb92649..fe16bc46 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -163,6 +163,8 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { PyObject_GetAttrString(py_module, "queue_get"); py_functions[PY_FUNC_QUEUE_NEW_ENTRY] = PyObject_GetAttrString(py_module, "queue_new_entry"); + py_functions[PY_FUNC_INTROSPECTION] = + PyObject_GetAttrString(py_module, "introspection"); py_functions[PY_FUNC_DEINIT] = PyObject_GetAttrString(py_module, "deinit"); if (!py_functions[PY_FUNC_DEINIT]) FATAL("deinit function not found in python module"); @@ -381,6 +383,15 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, } + #ifdef INTROSPECTION + if (py_functions[PY_FUNC_INTROSPECTION]) { + + mutator->afl_custom_introspection = introspection_py; + + } + + #endif + OKF("Python mutator '%s' installed successfully.", module_name); /* Initialize the custom mutator */ @@ -679,6 +690,28 @@ u8 havoc_mutation_probability_py(void *py_mutator) { } +const char *introspection_py(void *py_mutator) { + + PyObject *py_args, *py_value; + + py_args = PyTuple_New(0); + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INTROSPECTION], + py_args); + Py_DECREF(py_args); + + if (py_value == NULL) { + + return NULL; + + } else { + + return PyByteArray_AsString(py_value); + + } + +} + u8 queue_get_py(void *py_mutator, const u8 *filename) { PyObject *py_args, *py_value; -- cgit v1.2.3 From 1dfd7df7c0e28b6f356bda714bedfc612bf2db75 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 10 Nov 2020 14:16:36 +0100 Subject: small fix to actually document custom mutator introspection --- src/afl-fuzz-one.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 64365ebb..0adc3719 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1846,12 +1846,6 @@ custom_mutator_stage: if (mutated_size > 0) { -#ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s CUSTOM-%s", - afl->queue_cur->fname, - target != NULL ? (char *)target->fname : "none"); -#endif - if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) { goto abandon_entry; -- cgit v1.2.3 From a3928e5a62c3ed4af321cc6030efc250b6a585c0 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 10 Nov 2020 14:20:41 +0100 Subject: small fix to actually document custom mutator introspection --- src/afl-fuzz-bitmap.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 132499d6..a4407af7 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -588,12 +588,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { add_to_queue(afl, queue_fn, len, 0); #ifdef INTROSPECTION - if (afl->mutation[0] != 0) { - - fprintf(afl->introspection_file, "QUEUE %s = %s\n", afl->mutation, - afl->queue_top->fname); - - } else if (afl->custom_mutators_count && afl->current_custom_fuzz) { + if (afl->custom_mutators_count && afl->current_custom_fuzz) { LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { @@ -612,6 +607,11 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { }); + } else if (afl->mutation[0] != 0) { + + fprintf(afl->introspection_file, "QUEUE %s = %s\n", afl->mutation, + afl->queue_top->fname); + } #endif @@ -689,11 +689,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { ++afl->unique_tmouts; #ifdef INTROSPECTION - if (afl->mutation[0] != 0) { - - fprintf(afl->introspection_file, "UNIQUE_TIMEOUT %s\n", afl->mutation); - - } else if (afl->custom_mutators_count && afl->current_custom_fuzz) { + if (afl->custom_mutators_count && afl->current_custom_fuzz) { LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { @@ -713,6 +709,10 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { }); + } else if (afl->mutation[0] != 0) { + + fprintf(afl->introspection_file, "UNIQUE_TIMEOUT %s\n", afl->mutation); + } #endif @@ -800,11 +800,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { ++afl->unique_crashes; #ifdef INTROSPECTION - if (afl->mutation[0] != 0) { - - fprintf(afl->introspection_file, "UNIQUE_CRASH %s\n", afl->mutation); - - } else if (afl->custom_mutators_count && afl->current_custom_fuzz) { + if (afl->custom_mutators_count && afl->current_custom_fuzz) { LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { @@ -823,6 +819,10 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { }); + } else if (afl->mutation[0] != 0) { + + fprintf(afl->introspection_file, "UNIQUE_CRASH %s\n", afl->mutation); + } #endif -- cgit v1.2.3 From 5357ae5f918cb358a541d4d8a4cbf678d7682242 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 10 Nov 2020 19:20:13 +0100 Subject: remove duplicate include --- src/afl-gotcpu.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/afl-gotcpu.c b/src/afl-gotcpu.c index bd0f7de6..1aea3e40 100644 --- a/src/afl-gotcpu.c +++ b/src/afl-gotcpu.c @@ -65,7 +65,6 @@ #define cpu_set_t cpuset_t #elif defined(__NetBSD__) #include - #include #elif defined(__APPLE__) #include #include -- cgit v1.2.3 From 54a312a5fe7d83fcee8b420868bc918622e9b3a6 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Fri, 13 Nov 2020 00:44:08 +0100 Subject: more small fixes --- src/afl-common.c | 2 +- src/afl-fuzz-python.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 19c9419b..8cf1a444 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -342,7 +342,7 @@ u8 *find_binary(u8 *fname) { if (stat(target_path, &st) || !S_ISREG(st.st_mode) || !(st.st_mode & 0111) || st.st_size < 4) { - free(target_path); + ck_free(target_path); FATAL("Program '%s' not found or not executable", fname); } diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index fe16bc46..596b733e 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -214,6 +214,7 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { PyErr_Print(); fprintf(stderr, "Failed to load \"%s\"\n", module_name); + free(py); return NULL; } -- cgit v1.2.3 From 1b75cc9f742ca6f5c95788269c66c346036b7233 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 30 Nov 2020 21:38:15 +0100 Subject: add DEBUGF --- src/afl-cc.c | 4 ++-- src/afl-ld-lto.c | 10 ++++------ src/afl-showmap.c | 4 ++-- 3 files changed, 8 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 25ed923a..6d39b890 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1582,7 +1582,7 @@ int main(int argc, char **argv, char **envp) { if (debug) { - SAYF(cMGN "[D]" cRST " cd '%s';", getthecwd()); + DEBUGF("cd '%s';", getthecwd()); for (i = 0; i < argc; i++) SAYF(" '%s'", argv[i]); SAYF("\n"); @@ -1610,7 +1610,7 @@ int main(int argc, char **argv, char **envp) { if (debug) { - SAYF(cMGN "[D]" cRST " cd '%s';", getthecwd()); + DEBUGF("cd '%s';", getthecwd()); for (i = 0; i < (s32)cc_par_cnt; i++) SAYF(" '%s'", cc_params[i]); SAYF("\n"); diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index 771e2d0d..e6ea1f1d 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -182,9 +182,7 @@ static void edit_params(int argc, char **argv) { instrim = 1; if (debug) - SAYF(cMGN "[D] " cRST - "passthrough=%s instrim=%d, gold_pos=%d, gold_present=%s " - "inst_present=%s rt_present=%s rt_lto_present=%s\n", + DEBUGF("passthrough=%s instrim=%d, gold_pos=%d, gold_present=%s inst_present=%s rt_present=%s rt_lto_present=%s\n", passthrough ? "true" : "false", instrim, gold_pos, gold_present ? "true" : "false", inst_present ? "true" : "false", rt_present ? "true" : "false", rt_lto_present ? "true" : "false"); @@ -280,7 +278,7 @@ int main(int argc, char **argv) { if (getcwd(thecwd, sizeof(thecwd)) != 0) strcpy(thecwd, "."); - SAYF(cMGN "[D] " cRST "cd \"%s\";", thecwd); + DEBUGF("cd \"%s\";", thecwd); for (i = 0; i < argc; i++) SAYF(" \"%s\"", argv[i]); SAYF("\n"); @@ -315,7 +313,7 @@ int main(int argc, char **argv) { if (debug) { - SAYF(cMGN "[D]" cRST " cd \"%s\";", thecwd); + DEBUGF("cd \"%s\";", thecwd); for (i = 0; i < ld_param_cnt; i++) SAYF(" \"%s\"", ld_params[i]); SAYF("\n"); @@ -333,7 +331,7 @@ int main(int argc, char **argv) { if (pid < 0) PFATAL("fork() failed"); if (waitpid(pid, &status, 0) <= 0) PFATAL("waitpid() failed"); - if (debug) SAYF(cMGN "[D] " cRST "linker result: %d\n", status); + if (debug) DEBUGF("linker result: %d\n", status); if (!just_version) { diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 69527007..a8e7d3f9 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -904,7 +904,7 @@ int main(int argc, char **argv_orig, char **envp) { if (getenv("AFL_DEBUG")) { - SAYF(cMGN "[D]" cRST); + DEBUGF(""); for (i = 0; i < argc; i++) SAYF(" %s", argv[i]); SAYF("\n"); @@ -1066,7 +1066,7 @@ int main(int argc, char **argv_orig, char **envp) { if (get_afl_env("AFL_DEBUG")) { int i = optind; - SAYF(cMGN "[D]" cRST " %s:", fsrv->target_path); + DEBUGF("%s:", fsrv->target_path); while (argv[i] != NULL) { SAYF(" \"%s\"", argv[i++]); -- cgit v1.2.3 From e769102491a4a5aa90afe57cce48211338133d3f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 30 Nov 2020 21:54:18 +0100 Subject: more DEBUGF --- src/afl-cc.c | 18 +++++------------- src/afl-ld-lto.c | 10 ++++++---- 2 files changed, 11 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 6d39b890..cc9854b6 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -354,11 +354,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = "-B"; cc_params[cc_par_cnt++] = obj_path; - if (clang_mode) { + if (clang_mode) { cc_params[cc_par_cnt++] = "-no-integrated-as"; } - cc_params[cc_par_cnt++] = "-no-integrated-as"; - - } } if (compiler_mode == GCC_PLUGIN) { @@ -708,7 +705,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { } if (getenv("AFL_NO_BUILTIN") || getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES") || - getenv("LAF_TRANSFORM_COMPARES") || getenv("AFL_LLVM_LAF_ALL") || lto_mode) { + getenv("LAF_TRANSFORM_COMPARES") || getenv("AFL_LLVM_LAF_ALL") || + lto_mode) { cc_params[cc_par_cnt++] = "-fno-builtin-strcmp"; cc_params[cc_par_cnt++] = "-fno-builtin-strncmp"; @@ -1002,16 +1000,11 @@ int main(int argc, char **argv, char **envp) { } - if (strncmp(callname, "afl-clang", 9) == 0) { clang_mode = 1; - if (strncmp(callname, "afl-clang++", 11) == 0) { - - plusplus_mode = 1; - - } + if (strncmp(callname, "afl-clang++", 11) == 0) { plusplus_mode = 1; } } @@ -1085,8 +1078,7 @@ int main(int argc, char **argv, char **envp) { if (instrument_mode == 0) instrument_mode = INSTRUMENT_CFG; else if (instrument_mode != INSTRUMENT_CFG) - FATAL( - "you cannot set AFL_LLVM_INSTRUMENT and AFL_LLVM_INSTRIM together"); + FATAL("you cannot set AFL_LLVM_INSTRUMENT and AFL_LLVM_INSTRIM together"); } diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index e6ea1f1d..16feaa80 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -182,10 +182,12 @@ static void edit_params(int argc, char **argv) { instrim = 1; if (debug) - DEBUGF("passthrough=%s instrim=%d, gold_pos=%d, gold_present=%s inst_present=%s rt_present=%s rt_lto_present=%s\n", - passthrough ? "true" : "false", instrim, gold_pos, - gold_present ? "true" : "false", inst_present ? "true" : "false", - rt_present ? "true" : "false", rt_lto_present ? "true" : "false"); + DEBUGF( + "passthrough=%s instrim=%d, gold_pos=%d, gold_present=%s " + "inst_present=%s rt_present=%s rt_lto_present=%s\n", + passthrough ? "true" : "false", instrim, gold_pos, + gold_present ? "true" : "false", inst_present ? "true" : "false", + rt_present ? "true" : "false", rt_lto_present ? "true" : "false"); for (i = 1; i < argc; i++) { -- cgit v1.2.3 From 8584f9d2b5de9687c518c672e471f4f8cd9166fa Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 1 Dec 2020 13:13:11 +0100 Subject: added AFL_NO_AUTODICT --- src/afl-forkserver.c | 125 +++++++++++++++++++++++++++------------------------ src/afl-fuzz.c | 1 + 2 files changed, 68 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 3814a77e..01ef1d9e 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -348,9 +348,10 @@ static void report_error_and_exit(int error) { 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; - s32 rlen; + int st_pipe[2], ctl_pipe[2]; + s32 status; + s32 rlen; + char *ignore_autodict = getenv("AFL_NO_AUTODICT"); if (!be_quiet) { ACTF("Spinning up the fork server..."); } @@ -607,7 +608,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, fsrv->use_shmem_fuzz = 1; if (!be_quiet) { ACTF("Using SHARED MEMORY FUZZING feature."); } - if ((status & FS_OPT_AUTODICT) == 0) { + if ((status & FS_OPT_AUTODICT) == 0 || ignore_autodict) { u32 send_status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ); if (write(fsrv->fsrv_ctl_fd, &send_status, 4) != 4) { @@ -660,101 +661,109 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if ((status & FS_OPT_AUTODICT) == FS_OPT_AUTODICT) { - if (fsrv->add_extra_func == NULL || fsrv->afl_ptr == NULL) { + if (ignore_autodict) { - // this is not afl-fuzz - or it is cmplog - we deny and return - if (fsrv->use_shmem_fuzz) { + if (!be_quiet) { WARNF("Ignoring offered AUTODICT feature."); } - status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ); + } else { - } else { + if (fsrv->add_extra_func == NULL || fsrv->afl_ptr == NULL) { - status = (FS_OPT_ENABLED); + // this is not afl-fuzz - or it is cmplog - we deny and return + if (fsrv->use_shmem_fuzz) { - } + status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ); - if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) { + } else { - FATAL("Writing to forkserver failed."); + status = (FS_OPT_ENABLED); - } + } - return; + if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) { - } + FATAL("Writing to forkserver failed."); - if (!be_quiet) { ACTF("Using AUTODICT feature."); } + } - if (fsrv->use_shmem_fuzz) { + return; - status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ); + } - } else { + if (!be_quiet) { ACTF("Using AUTODICT feature."); } - status = (FS_OPT_ENABLED | FS_OPT_AUTODICT); + if (fsrv->use_shmem_fuzz) { - } + status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ); - if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) { + } else { - FATAL("Writing to forkserver failed."); + status = (FS_OPT_ENABLED | FS_OPT_AUTODICT); - } + } - if (read(fsrv->fsrv_st_fd, &status, 4) != 4) { + if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) { - FATAL("Reading from forkserver failed."); + FATAL("Writing to forkserver failed."); - } + } - if (status < 2 || (u32)status > 0xffffff) { + if (read(fsrv->fsrv_st_fd, &status, 4) != 4) { - FATAL("Dictionary has an illegal size: %d", status); + FATAL("Reading from forkserver failed."); - } + } - u32 offset = 0, count = 0; - u32 len = status; - u8 *dict = ck_alloc(len); - if (dict == NULL) { + if (status < 2 || (u32)status > 0xffffff) { - FATAL("Could not allocate %u bytes of autodictionary memory", len); + FATAL("Dictionary has an illegal size: %d", status); - } + } - while (len != 0) { + u32 offset = 0, count = 0; + u32 len = status; + u8 *dict = ck_alloc(len); + if (dict == NULL) { - rlen = read(fsrv->fsrv_st_fd, dict + offset, len); - if (rlen > 0) { + FATAL("Could not allocate %u bytes of autodictionary memory", len); - len -= rlen; - offset += rlen; + } - } else { + while (len != 0) { - FATAL( - "Reading autodictionary fail at position %u with %u bytes " - "left.", - offset, len); + 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++; - 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); } - if (!be_quiet) { ACTF("Loaded %u autodictionary entries", count); } - ck_free(dict); - } } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index b60908da..b91d862d 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -187,6 +187,7 @@ static void usage(u8 *argv0, int more_help) { " used. Defaults to 200.\n" "AFL_NO_AFFINITY: do not check for an unused cpu core to use for fuzzing\n" "AFL_NO_ARITH: skip arithmetic mutations in deterministic stage\n" + "AFL_NO_AUTODICT: do not load an offered auto dictionary compiled into a target\n" "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" -- cgit v1.2.3 From c05e4efbe9b4e7d1ff078b7a392621f2ca7572e6 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 1 Dec 2020 14:40:30 +0100 Subject: renamed examples/ to utils/ --- src/afl-as.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-as.c b/src/afl-as.c index 7d70bfcd..3d6f7d5e 100644 --- a/src/afl-as.c +++ b/src/afl-as.c @@ -27,7 +27,7 @@ utility has right now is to be able to skip them gracefully and allow the compilation process to continue. - That said, see examples/clang_asm_normalize/ for a solution that may + That said, see utils/clang_asm_normalize/ for a solution that may allow clang users to make things work even with hand-crafted assembly. Just note that there is no equivalent for GCC. -- cgit v1.2.3 From 1890d7b9cf5a32368c0700ef790f97087b948e1f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 2 Dec 2020 15:03:21 +0100 Subject: very complete runtime lookup rewrite --- src/afl-cc.c | 197 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 112 insertions(+), 85 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index cc9854b6..2b5ae7c3 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -106,20 +106,42 @@ u8 *getthecwd() { } -/* Try to find the runtime libraries. If that fails, abort. */ +/* Try to find a specific runtime we need, returns NULL on fail. */ + +/* + in find_object() we look here: + + 1. if obj_path is already set we look there first + 2. then we check the $AFL_PATH environment variable location if set + 3. next we check argv[0] if has path information and use it + a) we also check ../lib/ + 4. if 3. failed we check /proc (only Linux, Android, NetBSD, DragonFly, and + FreeBSD with procfs + a) and check here in ../lib/ too + 5. we look into the AFL_PATH define (usually /usr/local/lib/afl) + 6. we finally try the current directory + + if this all fail - we fail. +*/ static u8 *find_object(u8 *obj, u8 *argv0) { u8 *afl_path = getenv("AFL_PATH"); u8 *slash = NULL, *tmp; + if (obj_path) { + + tmp = alloc_printf("%s/%s", obj_path, obj); + + if (!access(tmp, R_OK)) { return tmp; } + + ck_free(tmp); + + } + if (afl_path) { -#ifdef __ANDROID__ tmp = alloc_printf("%s/%s", afl_path, obj); -#else - tmp = alloc_printf("%s/%s", afl_path, obj); -#endif if (!access(tmp, R_OK)) { @@ -132,125 +154,117 @@ static u8 *find_object(u8 *obj, u8 *argv0) { } - if (argv0) slash = strrchr(argv0, '/'); + if (argv0) { - if (slash) { + slash = strrchr(argv0, '/'); - u8 *dir; + if (slash) { - *slash = 0; - dir = ck_strdup(argv0); - *slash = '/'; + u8 *dir = ck_strdup(argv0); -#ifdef __ANDROID__ - tmp = alloc_printf("%s/%s", dir, obj); -#else - tmp = alloc_printf("%s/%s", dir, obj); -#endif + slash = strrchr(dir, '/'); + *slash = 0; - if (!access(tmp, R_OK)) { + tmp = alloc_printf("%s/%s", dir, obj); - obj_path = dir; - return tmp; + if (!access(tmp, R_OK)) { - } + obj_path = dir; + return tmp; - ck_free(tmp); - ck_free(dir); + } - } + ck_free(tmp); + tmp = alloc_printf("%s/../lib/%s", dir, obj); - tmp = alloc_printf("%s/%s", AFL_PATH, obj); -#ifdef __ANDROID__ - if (!access(tmp, R_OK)) { + if (!access(tmp, R_OK)) { -#else - if (!access(tmp, R_OK)) { + u8 *dir2 = alloc_printf("%s/../lib", dir); + obj_path = dir2; + ck_free(dir); + return tmp; -#endif + } - obj_path = AFL_PATH; - return tmp; + ck_free(tmp); + ck_free(dir); - } + } else { - ck_free(tmp); - return NULL; + char *procname = NULL; +#if defined(__FreeBSD__) || defined(__DragonFly__) + procname = "/proc/curproc/file"; + #elsif defined(__linux__) || defined(__ANDROID__) + procname = "/proc/self/exe"; + #elsif defined(__NetBSD__) + procname = "/proc/curproc/exe"; +#endif + if (procname) { -} + char exepath[PATH_MAX]; + ssize_t exepath_len = readlink(procname, exepath, sizeof(exepath)); + if (exepath_len > 0 && exepath_len < PATH_MAX) { -/* Try to find the runtime libraries. If that fails, abort. */ + exepath[exepath_len] = 0; + slash = strrchr(exepath, '/'); -static void find_obj(u8 *argv0) { + if (slash) { - u8 *afl_path = getenv("AFL_PATH"); - u8 *slash, *tmp; + *slash = 0; + tmp = alloc_printf("%s/%s", exepath, obj); - if (afl_path) { + if (!access(tmp, R_OK)) { -#ifdef __ANDROID__ - tmp = alloc_printf("%s/afl-compiler-rt.so", afl_path); -#else - tmp = alloc_printf("%s/afl-compiler-rt.o", afl_path); -#endif + u8 *dir = alloc_printf("%s/../lib/", exepath); + obj_path = dir; + return tmp; - if (!access(tmp, R_OK)) { + } - obj_path = afl_path; - ck_free(tmp); - return; + ck_free(tmp); + tmp = alloc_printf("%s/../lib/%s", exepath, obj); - } + if (!access(tmp, R_OK)) { - ck_free(tmp); + u8 *dir = alloc_printf("%s/../lib/", exepath); + obj_path = dir; + return tmp; - } - - slash = strrchr(argv0, '/'); + } - if (slash) { + } - u8 *dir; + } - *slash = 0; - dir = ck_strdup(argv0); - *slash = '/'; + } -#ifdef __ANDROID__ - tmp = alloc_printf("%s/afl-compiler-rt.so", dir); -#else - tmp = alloc_printf("%s/afl-compiler-rt.o", dir); -#endif + } - if (!access(tmp, R_OK)) { + } - obj_path = dir; - ck_free(tmp); - return; + tmp = alloc_printf("%s/%s", AFL_PATH, obj); - } + if (!access(tmp, R_OK)) { - ck_free(tmp); - ck_free(dir); + obj_path = AFL_PATH; + return tmp; } -#ifdef __ANDROID__ - if (!access(AFL_PATH "/afl-compiler-rt.so", R_OK)) { + ck_free(tmp); -#else - if (!access(AFL_PATH "/afl-compiler-rt.o", R_OK)) { + tmp = alloc_printf("./%s", obj); -#endif + if (!access(tmp, R_OK)) { - obj_path = AFL_PATH; - return; + obj_path = "."; + return tmp; } - FATAL( - "Unable to find 'afl-compiler-rt.o' or 'afl-llvm-pass.so'. Please set " - "AFL_PATH"); + ck_free(tmp); + + return NULL; } @@ -360,8 +374,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (compiler_mode == GCC_PLUGIN) { - char *fplugin_arg = - alloc_printf("-fplugin=%s", find_object("afl-gcc-pass.so", argvnull)); + char *fplugin_arg = alloc_printf("-fplugin=%s/afl-gcc-pass.so", obj_path); cc_params[cc_par_cnt++] = fplugin_arg; } @@ -1594,10 +1607,24 @@ int main(int argc, char **argv, char **envp) { if (!be_quiet && cmplog_mode) printf("CmpLog mode by \n"); -#ifndef __ANDROID__ - find_obj(argv[0]); +#ifdef __ANDROID__ + ptr = find_object("afl-compiler-rt.so", argv[0]); +#else + ptr = find_object("afl-compiler-rt.o", argv[0]); #endif + if (debug) { DEBUGF("obj_path=%s\n", obj_path); } + + if (!ptr) { + + FATAL( + "Unable to find 'afl-compiler-rt.o'. Please set the AFL_PATH " + "environment variable."); + + } + + ck_free(ptr); + edit_params(argc, argv, envp); if (debug) { -- cgit v1.2.3 From 0f803c63dfb1dafdef3bfe1b43674157efcd7107 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 2 Dec 2020 15:08:08 +0100 Subject: move debug print --- src/afl-cc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 2b5ae7c3..854359e2 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1613,8 +1613,6 @@ int main(int argc, char **argv, char **envp) { ptr = find_object("afl-compiler-rt.o", argv[0]); #endif - if (debug) { DEBUGF("obj_path=%s\n", obj_path); } - if (!ptr) { FATAL( @@ -1623,6 +1621,8 @@ int main(int argc, char **argv, char **envp) { } + if (debug) { DEBUGF("rt=%s obj_path=%s\n", ptr, obj_path); } + ck_free(ptr); edit_params(argc, argv, envp); -- cgit v1.2.3 From a2e2fae840e9946c7994ac6807bed8496d71af56 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 3 Dec 2020 14:43:06 +0100 Subject: AFL_CRASH_EXITCODE env var added, u8->bool --- src/afl-analyze.c | 4 ++-- src/afl-common.c | 4 ++-- src/afl-forkserver.c | 22 +++++++++++++++------- src/afl-fuzz-init.c | 27 +++++++++++++++++++++++++-- src/afl-fuzz-state.c | 7 +++++++ src/afl-fuzz.c | 26 ++++++++++++++++++++++++-- src/afl-showmap.c | 19 +++++++++++++++++++ src/afl-tmin.c | 32 +++++++++++++++++++++++++------- 8 files changed, 119 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/afl-analyze.c b/src/afl-analyze.c index c8acebb3..2780deff 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -78,9 +78,9 @@ static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */ static s32 dev_null_fd = -1; /* FD to /dev/null */ -static u8 edges_only, /* Ignore hit counts? */ +static bool edges_only, /* Ignore hit counts? */ use_hex_offsets, /* Show hex offsets? */ - use_stdin = 1; /* Use stdin for program input? */ + use_stdin = true; /* Use stdin for program input? */ static volatile u8 stop_soon, /* Ctrl-C pressed? */ child_timed_out; /* Child timed out? */ diff --git a/src/afl-common.c b/src/afl-common.c index 8cf1a444..ed0b0e53 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -46,7 +46,7 @@ u8 be_quiet = 0; u8 *doc_path = ""; u8 last_intr = 0; -void detect_file_args(char **argv, u8 *prog_in, u8 *use_stdin) { +void detect_file_args(char **argv, u8 *prog_in, bool *use_stdin) { u32 i = 0; u8 cwd[PATH_MAX]; @@ -63,7 +63,7 @@ void detect_file_args(char **argv, u8 *prog_in, u8 *use_stdin) { if (!prog_in) { FATAL("@@ syntax is not supported by this tool."); } - *use_stdin = 0; + *use_stdin = false; if (prog_in[0] != 0) { // not afl-showmap special case diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 01ef1d9e..20117c1d 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -76,8 +76,8 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) { fsrv->dev_urandom_fd = -1; /* Settings */ - fsrv->use_stdin = 1; - fsrv->no_unlink = 0; + fsrv->use_stdin = true; + fsrv->no_unlink = false; fsrv->exec_tmout = EXEC_TIMEOUT; fsrv->init_tmout = EXEC_TIMEOUT * FORK_WAIT_MULT; fsrv->mem_limit = MEM_LIMIT; @@ -86,8 +86,11 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) { /* exec related stuff */ fsrv->child_pid = -1; fsrv->map_size = get_map_size(); - fsrv->use_fauxsrv = 0; - fsrv->last_run_timed_out = 0; + fsrv->use_fauxsrv = false; + fsrv->last_run_timed_out = false; + + fsrv->uses_crash_exitcode = false; + fsrv->uses_asan = false; fsrv->init_child_func = fsrv_exec_child; @@ -109,6 +112,8 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->dev_urandom_fd = from->dev_urandom_fd; fsrv_to->out_fd = from->out_fd; // not sure this is a good idea fsrv_to->no_unlink = from->no_unlink; + fsrv_to->uses_crash_exitcode = from->uses_crash_exitcode; + fsrv_to->crash_exitcode = from->crash_exitcode; // These are forkserver specific. fsrv_to->out_dir_fd = -1; @@ -1136,10 +1141,13 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, } - /* A somewhat nasty hack for MSAN, which doesn't support abort_on_error and - must use a special exit code. */ + /* MSAN in uses_asan mode uses a special exit code as it doesn't support + abort_on_error. + On top, a user may specify a custom AFL_CRASH_EXITCODE. Handle both here. */ - if (fsrv->uses_asan && WEXITSTATUS(fsrv->child_status) == MSAN_ERROR) { + if ((fsrv->uses_asan && WEXITSTATUS(fsrv->child_status) == MSAN_ERROR) || + (fsrv->uses_crash_exitcode && + WEXITSTATUS(fsrv->child_status) == fsrv->crash_exitcode)) { fsrv->last_kill_signal = 0; return FSRV_RUN_CRASH; diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 0360cdb0..6707340b 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -868,7 +868,19 @@ void perform_dry_run(afl_state_t *afl) { if (skip_crashes) { - WARNF("Test case results in a crash (skipping)"); + if (afl->fsrv.uses_crash_exitcode) { + + WARNF( + "Test case results in a crash or AFL_CRASH_EXITCODE %d " + "(skipping)", + (int)(s8)afl->fsrv.crash_exitcode); + + } else { + + WARNF("Test case results in a crash (skipping)"); + + } + q->cal_failed = CAL_CHANCES; ++cal_failures; break; @@ -954,7 +966,18 @@ void perform_dry_run(afl_state_t *afl) { #undef MSG_ULIMIT_USAGE #undef MSG_FORK_ON_APPLE - WARNF("Test case '%s' results in a crash, skipping", fn); + if (afl->fsrv.uses_crash_exitcode) { + + WARNF( + "Test case '%s' results in a crash or AFL_CRASH_EXITCODE %d, " + "skipping", + fn, (int)(s8)afl->fsrv.crash_exitcode); + + } else { + + WARNF("Test case '%s' results in a crash, skipping", fn); + + } /* Remove from fuzzing queue but keep for splicing */ diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 489d4e53..73b94466 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -394,6 +394,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_statsd_tags_flavor = (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_CRASH_EXITCODE", + + afl_environment_variable_len)) { + + afl->afl_env.afl_crash_exitcode = + (u8 *)get_afl_env(afl_environment_variables[i]); + } } else { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index b91d862d..eb5e9307 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -26,6 +26,7 @@ #include "afl-fuzz.h" #include "cmplog.h" #include +#include #ifndef USEMMAP #include #include @@ -165,6 +166,7 @@ static void usage(u8 *argv0, int more_help) { "AFL_AUTORESUME: resume fuzzing if directory specified by -o already exists\n" "AFL_BENCH_JUST_ONE: run the target just once\n" "AFL_BENCH_UNTIL_CRASH: exit soon when the first crashing input has been found\n" + "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n" "AFL_CUSTOM_MUTATOR_LIBRARY: lib with afl_custom_fuzz() to mutate inputs\n" "AFL_CUSTOM_MUTATOR_ONLY: avoid AFL++'s internal mutators\n" "AFL_CYCLE_SCHEDULES: after completing a cycle, switch to a different -p schedule\n" @@ -702,7 +704,7 @@ int main(int argc, char **argv_orig, char **envp) { case 'N': /* Unicorn mode */ if (afl->no_unlink) { FATAL("Multiple -N options not supported"); } - afl->fsrv.no_unlink = afl->no_unlink = 1; + afl->fsrv.no_unlink = (afl->no_unlink = true); break; @@ -1135,6 +1137,23 @@ int main(int argc, char **argv_orig, char **envp) { } + if (afl->afl_env.afl_crash_exitcode) { + + long exitcode = strtol(afl->afl_env.afl_crash_exitcode, NULL, 10); + if ((!exitcode && (errno == EINVAL || errno == ERANGE)) || + exitcode < -127 || exitcode > 128) { + + FATAL("Invalid crash exitcode, expected -127 to 128, but got %s", + afl->afl_env.afl_crash_exitcode); + + } + + afl->fsrv.uses_crash_exitcode = true; + // WEXITSTATUS is 8 bit unsigned + afl->fsrv.crash_exitcode = (u8)exitcode; + + } + if (afl->non_instrumented_mode == 2 && afl->no_forkserver) { FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive"); @@ -1486,9 +1505,12 @@ int main(int argc, char **argv_orig, char **envp) { cull_queue(afl); - if (!afl->pending_not_fuzzed) + if (!afl->pending_not_fuzzed) { + FATAL("We need at least on valid input seed that does not crash!"); + } + show_init_stats(afl); if (unlikely(afl->old_seed_selection)) seek_to = find_start_position(afl); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index a8e7d3f9..e07e76c8 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -667,6 +667,8 @@ static void usage(u8 *argv0) { "AFL_CMIN_CRASHES_ONLY: (cmin_mode) only write tuples for crashing " "inputs\n" "AFL_CMIN_ALLOW_ANY: (cmin_mode) write tuples for crashing inputs also\n" + "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as " + "crash\n" "AFL_DEBUG: enable extra developer output\n" "AFL_MAP_SIZE: the shared memory size for that target. must be >= the " "size\n" @@ -1090,6 +1092,23 @@ int main(int argc, char **argv_orig, char **envp) { } + if (getenv("AFL_CRASH_EXITCODE")) { + + long exitcode = strtol(getenv("AFL_CRASH_EXITCODE"), NULL, 10); + if ((!exitcode && (errno == EINVAL || errno == ERANGE)) || + exitcode < -127 || exitcode > 128) { + + FATAL("Invalid crash exitcode, expected -127 to 128, but got %s", + getenv("AFL_CRASH_EXITCODE")); + + } + + fsrv->uses_crash_exitcode = true; + // WEXITSTATUS is 8 bit unsigned + fsrv->crash_exitcode = (u8)exitcode; + + } + afl_fsrv_start(fsrv, use_argv, &stop_soon, (get_afl_env("AFL_DEBUG_CHILD") || get_afl_env("AFL_DEBUG_CHILD_OUTPUT")) diff --git a/src/afl-tmin.c b/src/afl-tmin.c index e4fb068d..b9045551 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -841,17 +842,17 @@ static void usage(u8 *argv0) { "For additional tips, please consult %s/README.md.\n\n" "Environment variables used:\n" - "TMPDIR: directory to use for temporary input files\n" - "ASAN_OPTIONS: custom settings for ASAN\n" - " (must contain abort_on_error=1 and symbolize=0)\n" - "MSAN_OPTIONS: custom settings for MSAN\n" - " (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n" + "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n" + "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n" "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n" " the target was compiled for\n" "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" "AFL_TMIN_EXACT: require execution paths to match for crashing inputs\n" - "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n" - + "ASAN_OPTIONS: custom settings for ASAN\n" + " (must contain abort_on_error=1 and symbolize=0)\n" + "MSAN_OPTIONS: custom settings for MSAN\n" + " (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n" + "TMPDIR: directory to use for temporary input files\n" , argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path); exit(1); @@ -1122,6 +1123,23 @@ int main(int argc, char **argv_orig, char **envp) { } + if (getenv("AFL_CRASH_EXITCODE")) { + + long exitcode = strtol(getenv("AFL_CRASH_EXITCODE"), NULL, 10); + if ((!exitcode && (errno == EINVAL || errno == ERANGE)) || + exitcode < -127 || exitcode > 128) { + + FATAL("Invalid crash exitcode, expected -127 to 128, but got %s", + getenv("AFL_CRASH_EXITCODE")); + + } + + fsrv->uses_crash_exitcode = true; + // WEXITSTATUS is 8 bit unsigned + fsrv->crash_exitcode = (u8)exitcode; + + } + shm_fuzz = ck_alloc(sizeof(sharedmem_t)); /* initialize cmplog_mode */ -- cgit v1.2.3 From 295ddaf96b411b41017e609b6b3537db78147dfa Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 3 Dec 2020 15:19:10 +0100 Subject: fix for afl-cc --- src/afl-cc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 854359e2..cc4f44f5 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -114,10 +114,10 @@ u8 *getthecwd() { 1. if obj_path is already set we look there first 2. then we check the $AFL_PATH environment variable location if set 3. next we check argv[0] if has path information and use it - a) we also check ../lib/ + a) we also check ../lib/afl 4. if 3. failed we check /proc (only Linux, Android, NetBSD, DragonFly, and FreeBSD with procfs - a) and check here in ../lib/ too + a) and check here in ../lib/afl too 5. we look into the AFL_PATH define (usually /usr/local/lib/afl) 6. we finally try the current directory @@ -175,11 +175,11 @@ static u8 *find_object(u8 *obj, u8 *argv0) { } ck_free(tmp); - tmp = alloc_printf("%s/../lib/%s", dir, obj); + tmp = alloc_printf("%s/../lib/afl/%s", dir, obj); if (!access(tmp, R_OK)) { - u8 *dir2 = alloc_printf("%s/../lib", dir); + u8 *dir2 = alloc_printf("%s/../lib/afl", dir); obj_path = dir2; ck_free(dir); return tmp; @@ -215,18 +215,18 @@ static u8 *find_object(u8 *obj, u8 *argv0) { if (!access(tmp, R_OK)) { - u8 *dir = alloc_printf("%s/../lib/", exepath); + u8 *dir = alloc_printf("%s", exepath); obj_path = dir; return tmp; } ck_free(tmp); - tmp = alloc_printf("%s/../lib/%s", exepath, obj); + tmp = alloc_printf("%s/../lib/afl/%s", exepath, obj); if (!access(tmp, R_OK)) { - u8 *dir = alloc_printf("%s/../lib/", exepath); + u8 *dir = alloc_printf("%s/../lib/afl/", exepath); obj_path = dir; return tmp; -- cgit v1.2.3 From a19b3022d93195d3703817c728817d7e071e89fe Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 3 Dec 2020 19:22:44 +0100 Subject: afl_custom_describe api added --- src/afl-fuzz-bitmap.c | 63 +++++++++++++++++++++++++++++--------- src/afl-fuzz-mutators.c | 80 ++++++++++++++++++++++++++++++++++++++++--------- src/afl-fuzz-one.c | 9 ++++-- 3 files changed, 122 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 2d14b04e..a78bf374 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -425,7 +425,7 @@ void minimize_bits(afl_state_t *afl, u8 *dst, u8 *src) { /* Construct a file name for a new test case, capturing the operation that led to its discovery. Returns a ptr to afl->describe_op_buf_256. */ -u8 *describe_op(afl_state_t *afl, u8 hnb) { +u8 *describe_op(afl_state_t *afl, u8 new_bits) { u8 *ret = afl->describe_op_buf_256; @@ -445,29 +445,64 @@ u8 *describe_op(afl_state_t *afl, u8 hnb) { sprintf(ret + strlen(ret), ",time:%llu", get_cur_time() - afl->start_time); - sprintf(ret + strlen(ret), ",op:%s", afl->stage_short); + if (afl->current_custom_fuzz && + afl->current_custom_fuzz->afl_custom_describe) { - if (afl->stage_cur_byte >= 0) { + /* We are currently in a custom mutator that supports afl_custom_describe, + * use it! */ - sprintf(ret + strlen(ret), ",pos:%d", afl->stage_cur_byte); + size_t len_current = strlen(ret); + ret[len_current++] = ','; + ret[len_current++] = '\0'; - if (afl->stage_val_type != STAGE_VAL_NONE) { + size_t size_left = + sizeof(afl->describe_op_buf_256) - len_current - strlen(",+cov") - 2; + assert(size_left > 0); - sprintf(ret + strlen(ret), ",val:%s%+d", - (afl->stage_val_type == STAGE_VAL_BE) ? "be:" : "", - afl->stage_cur_val); + const char *custom_description = + afl->current_custom_fuzz->afl_custom_describe( + afl->current_custom_fuzz->data, size_left); + if (!custom_description || !custom_description[0]) { + + DEBUGF("Error getting a description from afl_custom_describe"); + /* Take the stage name as description fallback */ + sprintf(ret + len_current, "op:%s", afl->stage_short); + + } else { + + /* We got a proper custom description, use it */ + strncat(ret + len_current, custom_description, size_left); } } else { - sprintf(ret + strlen(ret), ",rep:%d", afl->stage_cur_val); + /* Normal testcase descriptions start here */ + sprintf(ret + strlen(ret), ",op:%s", afl->stage_short); + + if (afl->stage_cur_byte >= 0) { + + sprintf(ret + strlen(ret), ",pos:%d", afl->stage_cur_byte); + + if (afl->stage_val_type != STAGE_VAL_NONE) { + + sprintf(ret + strlen(ret), ",val:%s%+d", + (afl->stage_val_type == STAGE_VAL_BE) ? "be:" : "", + afl->stage_cur_val); + + } + + } else { + + sprintf(ret + strlen(ret), ",rep:%d", afl->stage_cur_val); + + } } } - if (hnb == 2) { strcat(ret, ",+cov"); } + if (new_bits == 2) { strcat(ret, ",+cov"); } return ret; @@ -540,7 +575,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (unlikely(len == 0)) { return 0; } u8 *queue_fn = ""; - u8 hnb = '\0'; + u8 new_bits = '\0'; s32 fd; u8 keeping = 0, res; u64 cksum = 0; @@ -566,7 +601,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { /* Keep only if there are new bits in the map, add to queue for future fuzzing, etc. */ - if (!(hnb = has_new_bits(afl, afl->virgin_bits))) { + if (!(new_bits = has_new_bits(afl, afl->virgin_bits))) { if (unlikely(afl->crash_mode)) { ++afl->total_crashes; } return 0; @@ -576,7 +611,7 @@ 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_paths, describe_op(afl, hnb)); + afl->queued_paths, describe_op(afl, new_bits)); #else @@ -619,7 +654,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #endif - if (hnb == 2) { + if (new_bits == 2) { afl->queue_top->has_new_cov = 1; ++afl->queued_with_cov; diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 1d14f657..0c85458e 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -151,7 +151,11 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { /* Mutator */ /* "afl_custom_init", optional for backward compatibility */ mutator->afl_custom_init = dlsym(dh, "afl_custom_init"); - if (!mutator->afl_custom_init) FATAL("Symbol 'afl_custom_init' not found."); + if (!mutator->afl_custom_init) { + + FATAL("Symbol 'afl_custom_init' not found."); + + } /* "afl_custom_fuzz" or "afl_custom_mutator", required */ mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz"); @@ -161,49 +165,74 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { WARNF("Symbol 'afl_custom_fuzz' not found. Try 'afl_custom_mutator'."); mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_mutator"); - if (!mutator->afl_custom_fuzz) + if (!mutator->afl_custom_fuzz) { + WARNF("Symbol 'afl_custom_mutator' not found."); + } + } /* "afl_custom_introspection", optional */ #ifdef INTROSPECTION mutator->afl_custom_introspection = dlsym(dh, "afl_custom_introspection"); - if (!mutator->afl_custom_introspection) + if (!mutator->afl_custom_introspection) { + ACTF("optional symbol 'afl_custom_introspection' not found."); + + } + #endif /* "afl_custom_fuzz_count", optional */ mutator->afl_custom_fuzz_count = dlsym(dh, "afl_custom_fuzz_count"); - if (!mutator->afl_custom_fuzz_count) + if (!mutator->afl_custom_fuzz_count) { + ACTF("optional symbol 'afl_custom_fuzz_count' not found."); + } + /* "afl_custom_deinit", optional for backward compatibility */ mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit"); - if (!mutator->afl_custom_deinit) + if (!mutator->afl_custom_deinit) { + FATAL("Symbol 'afl_custom_deinit' not found."); + } + /* "afl_custom_post_process", optional */ mutator->afl_custom_post_process = dlsym(dh, "afl_custom_post_process"); - if (!mutator->afl_custom_post_process) + if (!mutator->afl_custom_post_process) { + ACTF("optional symbol 'afl_custom_post_process' not found."); + } + u8 notrim = 0; /* "afl_custom_init_trim", optional */ mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim"); - if (!mutator->afl_custom_init_trim) + if (!mutator->afl_custom_init_trim) { + ACTF("optional symbol 'afl_custom_init_trim' not found."); + } + /* "afl_custom_trim", optional */ mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim"); - if (!mutator->afl_custom_trim) + if (!mutator->afl_custom_trim) { + ACTF("optional symbol 'afl_custom_trim' not found."); + } + /* "afl_custom_post_trim", optional */ mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim"); - if (!mutator->afl_custom_post_trim) + if (!mutator->afl_custom_post_trim) { + ACTF("optional symbol 'afl_custom_post_trim' not found."); + } + if (notrim) { mutator->afl_custom_init_trim = NULL; @@ -217,31 +246,54 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { /* "afl_custom_havoc_mutation", optional */ mutator->afl_custom_havoc_mutation = dlsym(dh, "afl_custom_havoc_mutation"); - if (!mutator->afl_custom_havoc_mutation) + if (!mutator->afl_custom_havoc_mutation) { + ACTF("optional symbol 'afl_custom_havoc_mutation' not found."); + } + /* "afl_custom_havoc_mutation", optional */ mutator->afl_custom_havoc_mutation_probability = dlsym(dh, "afl_custom_havoc_mutation_probability"); - if (!mutator->afl_custom_havoc_mutation_probability) + if (!mutator->afl_custom_havoc_mutation_probability) { + ACTF("optional symbol 'afl_custom_havoc_mutation_probability' not found."); + } + /* "afl_custom_queue_get", optional */ mutator->afl_custom_queue_get = dlsym(dh, "afl_custom_queue_get"); - if (!mutator->afl_custom_queue_get) + if (!mutator->afl_custom_queue_get) { + ACTF("optional symbol 'afl_custom_queue_get' not found."); + } + /* "afl_custom_queue_new_entry", optional */ mutator->afl_custom_queue_new_entry = dlsym(dh, "afl_custom_queue_new_entry"); - if (!mutator->afl_custom_queue_new_entry) + if (!mutator->afl_custom_queue_new_entry) { + ACTF("optional symbol 'afl_custom_queue_new_entry' not found"); + } + + /* "afl_custom_describe", optional */ + mutator->afl_custom_describe = dlsym(dh, "afl_custom_describe"); + if (!mutator->afl_custom_describe) { + + ACTF("Symbol 'afl_custom_describe' not found."); + + } + OKF("Custom mutator '%s' installed successfully.", fn); /* Initialize the custom mutator */ - if (mutator->afl_custom_init) + if (mutator->afl_custom_init) { + mutator->data = mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF)); + } + mutator->stacked_custom = (mutator && mutator->afl_custom_havoc_mutation); mutator->stacked_custom_prob = 6; // like one of the default mutations in havoc diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 0adc3719..ca48f72a 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1790,11 +1790,16 @@ custom_mutator_stage: afl->current_custom_fuzz = el; - if (el->afl_custom_fuzz_count) + if (el->afl_custom_fuzz_count) { + afl->stage_max = el->afl_custom_fuzz_count(el->data, out_buf, len); - else + + } else { + afl->stage_max = saved_max; + } + has_custom_fuzz = true; afl->stage_short = el->name_short; -- cgit v1.2.3 From 1f34b9f8e185998e4c9c4b96b0c1878b6615115a Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 4 Dec 2020 05:28:36 +0100 Subject: added python mutator, documentation --- src/afl-fuzz-python.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 9ac4403b..8760194c 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -111,6 +111,37 @@ static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf, } +static const char *custom_describe_py(void * py_mutator, + size_t max_description_len) { + + PyObject *py_args, *py_value; + + py_args = PyTuple_New(1); + + PyLong_FromSize_t(max_description_len); + + /* add_buf */ + py_value = PyLong_FromSize_t(max_description_len); + if (!py_value) { + + Py_DECREF(py_args); + FATAL("Failed to convert arguments"); + + } + + PyTuple_SetItem(py_args, 0, py_value); + + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_DESCRIBE], py_args); + + Py_DECREF(py_args); + + if (py_value != NULL) { return PyBytes_AsString(py_value); } + + return NULL; + +} + static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { (void)afl; @@ -156,6 +187,8 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "fuzz"); if (!py_functions[PY_FUNC_FUZZ]) py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "mutate"); + py_functions[PY_FUNC_DESCRIBE] = + PyObject_GetAttrString(py_module, "describe"); py_functions[PY_FUNC_FUZZ_COUNT] = PyObject_GetAttrString(py_module, "fuzz_count"); if (!py_functions[PY_FUNC_FUZZ]) @@ -342,6 +375,12 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, if (py_functions[PY_FUNC_FUZZ]) { mutator->afl_custom_fuzz = fuzz_py; } + if (py_functions[PY_FUNC_DESCRIBE]) { + + mutator->afl_custom_describe = custom_describe_py; + + } + if (py_functions[PY_FUNC_POST_PROCESS]) { mutator->afl_custom_post_process = post_process_py; -- cgit v1.2.3 From 1dbefc14eae4f7a189851785aa3f0982af4236f2 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 4 Dec 2020 14:25:18 +0100 Subject: fixed bugs in custom_describe, reported by wizche --- src/afl-fuzz-bitmap.c | 21 +++++++++++++-------- src/afl-fuzz-run.c | 3 ++- 2 files changed, 15 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index a78bf374..f920efa4 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -425,8 +425,10 @@ void minimize_bits(afl_state_t *afl, u8 *dst, u8 *src) { /* Construct a file name for a new test case, capturing the operation that led to its discovery. Returns a ptr to afl->describe_op_buf_256. */ -u8 *describe_op(afl_state_t *afl, u8 new_bits) { +u8 *describe_op(afl_state_t *afl, u8 new_bits, size_t max_description_len) { + size_t real_max_len = + MIN(max_description_len, sizeof(afl->describe_op_buf_256)); u8 *ret = afl->describe_op_buf_256; if (unlikely(afl->syncing_party)) { @@ -453,10 +455,9 @@ u8 *describe_op(afl_state_t *afl, u8 new_bits) { size_t len_current = strlen(ret); ret[len_current++] = ','; - ret[len_current++] = '\0'; + ret[len_current] = '\0'; - size_t size_left = - sizeof(afl->describe_op_buf_256) - len_current - strlen(",+cov") - 2; + size_t size_left = real_max_len - len_current - strlen(",+cov") - 2; assert(size_left > 0); const char *custom_description = @@ -504,6 +505,8 @@ u8 *describe_op(afl_state_t *afl, u8 new_bits) { if (new_bits == 2) { strcat(ret, ",+cov"); } + assert(strlen(ret) <= max_description_len); + return ret; } @@ -610,8 +613,9 @@ 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_paths, describe_op(afl, new_bits)); + queue_fn = alloc_printf( + "%s/queue/id:%06u,%s", afl->out_dir, afl->queued_paths, + describe_op(afl, new_bits, NAME_MAX - strlen("id:000000,"))); #else @@ -777,7 +781,8 @@ 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, - afl->unique_hangs, describe_op(afl, 0)); + afl->unique_hangs, + describe_op(afl, 0, NAME_MAX - strlen("id:000000,"))); #else @@ -822,7 +827,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir, afl->unique_crashes, afl->fsrv.last_kill_signal, - describe_op(afl, 0)); + describe_op(afl, 0, NAME_MAX - strlen("id:000000,sig:00,"))); #else diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index b716b8c8..5948d83a 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -79,7 +79,8 @@ write_to_testcase(afl_state_t *afl, void *mem, u32 len) { s32 doc_fd; char fn[PATH_MAX]; snprintf(fn, PATH_MAX, "%s/mutations/%09u:%s", afl->out_dir, - afl->document_counter++, describe_op(afl, 0)); + afl->document_counter++, + describe_op(afl, 0, NAME_MAX - strlen("000000000:"))); if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) { -- cgit v1.2.3 From f8c33f29e8cf7de30604be2c6818dd8d2d0ad3a6 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 5 Dec 2020 09:19:14 +0100 Subject: Typos --- src/afl-cc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index cc4f44f5..fcc10122 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -113,15 +113,15 @@ u8 *getthecwd() { 1. if obj_path is already set we look there first 2. then we check the $AFL_PATH environment variable location if set - 3. next we check argv[0] if has path information and use it + 3. next we check argv[0] if it has path information and use it a) we also check ../lib/afl 4. if 3. failed we check /proc (only Linux, Android, NetBSD, DragonFly, and - FreeBSD with procfs + FreeBSD with procfs) a) and check here in ../lib/afl too 5. we look into the AFL_PATH define (usually /usr/local/lib/afl) 6. we finally try the current directory - if this all fail - we fail. + if all this fails - we fail. */ static u8 *find_object(u8 *obj, u8 *argv0) { -- cgit v1.2.3 From 8f79116a15e53f0ecd4889ebf8980cc0cd85a494 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 5 Dec 2020 09:48:55 +0100 Subject: fix find_object proc search (#elsif -> #elif), optimize static if away --- src/afl-cc.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index fcc10122..1cd53f98 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -189,14 +189,25 @@ static u8 *find_object(u8 *obj, u8 *argv0) { ck_free(tmp); ck_free(dir); - } else { + } + +#if \ + defined(__FreeBSD__) \ +|| defined(__DragonFly__) \ +|| defined(__linux__) \ +|| defined(__ANDROID__) \ +|| defined(__NetBSD__) +#define HAS_PROC_FS 1 +#endif +#ifdef HAS_PROC_FS + else { char *procname = NULL; #if defined(__FreeBSD__) || defined(__DragonFly__) procname = "/proc/curproc/file"; - #elsif defined(__linux__) || defined(__ANDROID__) + #elif defined(__linux__) || defined(__ANDROID__) procname = "/proc/self/exe"; - #elsif defined(__NetBSD__) + #elif defined(__NetBSD__) procname = "/proc/curproc/exe"; #endif if (procname) { @@ -239,6 +250,8 @@ static u8 *find_object(u8 *obj, u8 *argv0) { } } +#endif +#undef HAS_PROC_FS } -- cgit v1.2.3 From 4c2e375e22a0b3c88380e6dd51dbac5d2c5ac5ff Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 7 Dec 2020 14:29:59 +0100 Subject: little fixes --- src/afl-cc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 1cd53f98..50334139 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -121,7 +121,8 @@ u8 *getthecwd() { 5. we look into the AFL_PATH define (usually /usr/local/lib/afl) 6. we finally try the current directory - if all this fails - we fail. + if all these attempts fail - we return NULL and the caller has to decide + what to do. */ static u8 *find_object(u8 *obj, u8 *argv0) { -- cgit v1.2.3 From e6de85861c4ec8fcc13a7f945bc8b3dfefa193bc Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 7 Dec 2020 14:36:04 +0100 Subject: fixes and code format --- src/afl-cc.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 50334139..273a9f2f 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -192,25 +192,21 @@ static u8 *find_object(u8 *obj, u8 *argv0) { } -#if \ - defined(__FreeBSD__) \ -|| defined(__DragonFly__) \ -|| defined(__linux__) \ -|| defined(__ANDROID__) \ -|| defined(__NetBSD__) -#define HAS_PROC_FS 1 +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__linux__) || \ + defined(__ANDROID__) || defined(__NetBSD__) + #define HAS_PROC_FS 1 #endif #ifdef HAS_PROC_FS else { char *procname = NULL; -#if defined(__FreeBSD__) || defined(__DragonFly__) + #if defined(__FreeBSD__) || defined(__DragonFly__) procname = "/proc/curproc/file"; #elif defined(__linux__) || defined(__ANDROID__) procname = "/proc/self/exe"; #elif defined(__NetBSD__) procname = "/proc/curproc/exe"; -#endif + #endif if (procname) { char exepath[PATH_MAX]; @@ -251,6 +247,7 @@ static u8 *find_object(u8 *obj, u8 *argv0) { } } + #endif #undef HAS_PROC_FS -- cgit v1.2.3 From 06ec5ab3d723bf7f0a2ee76be8b12c09fa870a9d Mon Sep 17 00:00:00 2001 From: Marcel Boehme Date: Mon, 7 Dec 2020 21:32:25 +0000 Subject: Sampling next seed by weight (hit_count, bitmap_size, exec_us) --- src/afl-fuzz-one.c | 6 ++++-- src/afl-fuzz-queue.c | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 36 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index ca48f72a..a48afffb 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -445,8 +445,10 @@ u8 fuzz_one_original(afl_state_t *afl) { if (unlikely(afl->not_on_tty)) { - ACTF("Fuzzing test case #%u (%u total, %llu uniq crashes found)...", - afl->current_entry, afl->queued_paths, afl->unique_crashes); + ACTF("Fuzzing test case #%u (%u total, %llu uniq crashes found, perf_score=%0.0f, exec_us=%llu, hits=%u, map=%u)...", + afl->current_entry, afl->queued_paths, afl->unique_crashes, + afl->queue_cur->perf_score, afl->queue_cur->exec_us, + afl->n_fuzz[afl->queue_cur->n_fuzz_entry], afl->queue_cur->bitmap_size); fflush(stdout); } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index f35b4f57..1e997c55 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -42,6 +42,21 @@ inline u32 select_next_queue_entry(afl_state_t *afl) { } +double compute_weight(afl_state_t *afl, struct queue_entry *q, double avg_exec_us, double avg_bitmap_size) { + + u32 hits = afl->n_fuzz[q->n_fuzz_entry]; + if (hits == 0) hits = 1; + + double weight = 1.0; + weight *= avg_exec_us / q->exec_us; + weight *= log(q->bitmap_size) / avg_bitmap_size; + weight /= log10(hits) + 1; + + if (q->favored) weight *= 5; + + return weight; +} + /* create the alias table that allows weighted random selection - expensive */ void create_alias_table(afl_state_t *afl) { @@ -65,25 +80,35 @@ void create_alias_table(afl_state_t *afl) { memset((void *)afl->alias_table, 0, n * sizeof(u32)); memset((void *)afl->alias_probability, 0, n * sizeof(double)); - double sum = 0; - + double avg_exec_us = 0.0; + double avg_bitmap_size = 0.0; for (i = 0; i < n; i++) { struct queue_entry *q = afl->queue_buf[i]; - - if (!q->disabled) { q->perf_score = calculate_score(afl, q); } - - sum += q->perf_score; + avg_exec_us += q->exec_us; + avg_bitmap_size += log(q->bitmap_size); } + avg_exec_us /= afl->queued_paths; + avg_bitmap_size /= afl->queued_paths; + double sum = 0; for (i = 0; i < n; i++) { struct queue_entry *q = afl->queue_buf[i]; - P[i] = (q->perf_score * n) / sum; + + if (!q->disabled) { + q->weight = compute_weight(afl, q, avg_exec_us, avg_bitmap_size); + q->perf_score = calculate_score(afl, q); + } + + sum += q->weight; } + for (i = 0; i < n; i++) + P[i] = (afl->queue_buf[i]->weight * n) / sum; + int nS = 0, nL = 0, s; for (s = (s32)n - 1; s >= 0; --s) { -- cgit v1.2.3 From 46156957bd120dc8d8bcd9da72f83574902c654f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 8 Dec 2020 11:07:11 +0100 Subject: fix aflfast changes --- src/afl-fuzz-one.c | 11 +++++--- src/afl-fuzz-queue.c | 73 +++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 59 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index a48afffb..e6fa6064 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -445,10 +445,13 @@ u8 fuzz_one_original(afl_state_t *afl) { if (unlikely(afl->not_on_tty)) { - ACTF("Fuzzing test case #%u (%u total, %llu uniq crashes found, perf_score=%0.0f, exec_us=%llu, hits=%u, map=%u)...", - afl->current_entry, afl->queued_paths, afl->unique_crashes, - afl->queue_cur->perf_score, afl->queue_cur->exec_us, - afl->n_fuzz[afl->queue_cur->n_fuzz_entry], afl->queue_cur->bitmap_size); + ACTF( + "Fuzzing test case #%u (%u total, %llu uniq crashes found, " + "perf_score=%0.0f, exec_us=%llu, hits=%u, map=%u)...", + afl->current_entry, afl->queued_paths, afl->unique_crashes, + afl->queue_cur->perf_score, afl->queue_cur->exec_us, + likely(afl->n_fuzz) ? afl->n_fuzz[afl->queue_cur->n_fuzz_entry] : 0, + afl->queue_cur->bitmap_size); fflush(stdout); } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 1e997c55..071e4a4c 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -42,7 +42,8 @@ inline u32 select_next_queue_entry(afl_state_t *afl) { } -double compute_weight(afl_state_t *afl, struct queue_entry *q, double avg_exec_us, double avg_bitmap_size) { +double compute_weight(afl_state_t *afl, struct queue_entry *q, + double avg_exec_us, double avg_bitmap_size) { u32 hits = afl->n_fuzz[q->n_fuzz_entry]; if (hits == 0) hits = 1; @@ -55,13 +56,15 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q, double avg_exec_u if (q->favored) weight *= 5; return weight; + } /* create the alias table that allows weighted random selection - expensive */ void create_alias_table(afl_state_t *afl) { - u32 n = afl->queued_paths, i = 0, a, g; + u32 n = afl->queued_paths, i = 0, a, g; + double sum = 0; afl->alias_table = (u32 *)afl_realloc((void **)&afl->alias_table, n * sizeof(u32)); @@ -80,34 +83,62 @@ void create_alias_table(afl_state_t *afl) { memset((void *)afl->alias_table, 0, n * sizeof(u32)); memset((void *)afl->alias_probability, 0, n * sizeof(double)); - double avg_exec_us = 0.0; - double avg_bitmap_size = 0.0; - for (i = 0; i < n; i++) { + if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) { - struct queue_entry *q = afl->queue_buf[i]; - avg_exec_us += q->exec_us; - avg_bitmap_size += log(q->bitmap_size); + double avg_exec_us = 0.0; + double avg_bitmap_size = 0.0; + for (i = 0; i < n; i++) { - } - avg_exec_us /= afl->queued_paths; - avg_bitmap_size /= afl->queued_paths; + struct queue_entry *q = afl->queue_buf[i]; + avg_exec_us += q->exec_us; + avg_bitmap_size += log(q->bitmap_size); - double sum = 0; - for (i = 0; i < n; i++) { + } + + avg_exec_us /= afl->queued_paths; + avg_bitmap_size /= afl->queued_paths; + + for (i = 0; i < n; i++) { - struct queue_entry *q = afl->queue_buf[i]; + struct queue_entry *q = afl->queue_buf[i]; + + if (!q->disabled) { + + q->weight = compute_weight(afl, q, avg_exec_us, avg_bitmap_size); + q->perf_score = calculate_score(afl, q); + + } + + sum += q->weight; - if (!q->disabled) { - q->weight = compute_weight(afl, q, avg_exec_us, avg_bitmap_size); - q->perf_score = calculate_score(afl, q); } - sum += q->weight; + for (i = 0; i < n; i++) { - } + P[i] = (afl->queue_buf[i]->weight * n) / sum; + + } + + } else { + + for (i = 0; i < n; i++) { + + struct queue_entry *q = afl->queue_buf[i]; + + if (!q->disabled) { q->perf_score = calculate_score(afl, q); } + + sum += q->perf_score; - for (i = 0; i < n; i++) - P[i] = (afl->queue_buf[i]->weight * n) / sum; + } + + for (i = 0; i < n; i++) { + + struct queue_entry *q = afl->queue_buf[i]; + P[i] = (q->perf_score * n) / sum; + + } + + } int nS = 0, nL = 0, s; for (s = (s32)n - 1; s >= 0; --s) { -- cgit v1.2.3 From da6cddab904e363775f157ceafa932f3cdaf6121 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 8 Dec 2020 11:30:05 +0100 Subject: fix asserts --- src/afl-fuzz-bitmap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index f920efa4..f1ca7400 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -457,8 +457,8 @@ u8 *describe_op(afl_state_t *afl, u8 new_bits, size_t max_description_len) { ret[len_current++] = ','; ret[len_current] = '\0'; - size_t size_left = real_max_len - len_current - strlen(",+cov") - 2; - assert(size_left > 0); + ssize_t size_left = real_max_len - len_current - strlen(",+cov") - 2; + if (unlikely(size_left <= 0)) FATAL("filename got too long"); const char *custom_description = afl->current_custom_fuzz->afl_custom_describe( @@ -505,7 +505,8 @@ u8 *describe_op(afl_state_t *afl, u8 new_bits, size_t max_description_len) { if (new_bits == 2) { strcat(ret, ",+cov"); } - assert(strlen(ret) <= max_description_len); + if (unlikely(strlen(ret) >= max_description_len)) + FATAL("describe string is too long"); return ret; -- cgit v1.2.3 From 6e61b2345cc35f101bac7594089dc57999f33b89 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 8 Dec 2020 20:33:41 +0100 Subject: more reporting on errors --- src/afl-forkserver.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 20117c1d..b1c29ba6 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1069,6 +1069,13 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, if (fsrv->child_pid <= 0) { if (*stop_soon_p) { return 0; } + + if ((fsrv->child_pid & FS_OPT_ERROR) && + FS_OPT_GET_ERROR(fsrv->child_pid) == FS_ERROR_SHM_OPEN) + FATAL( + "Target reported shared memory access failed (perhaps increase " + "shared memory available)."); + FATAL("Fork server is misbehaving (OOM?)"); } -- cgit v1.2.3 From 5bb51688e4187629b500842a14b9740d12d9829a Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 8 Dec 2020 21:54:18 +0100 Subject: small fixes --- src/afl-forkserver.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index b1c29ba6..38cd529f 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -62,6 +62,7 @@ static void fsrv_exec_child(afl_forkserver_t *fsrv, char **argv) { execv(fsrv->target_path, argv); + WARNF("Execv failed in forkserver."); } /* Initializes the struct */ @@ -526,8 +527,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, falling through. */ *(u32 *)fsrv->trace_bits = EXEC_FAIL_SIG; - fprintf(stderr, "Error: execv to target failed\n"); - exit(1); + FATAL("Error: execv to target failed\n"); } @@ -916,7 +916,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, " estimate the required amount of virtual memory for the " "binary.\n\n" - " - the target was compiled with afl-clang-lto and a constructor " + " - The target was compiled with afl-clang-lto and a constructor " "was\n" " instrumented, recompiling without AFL_LLVM_MAP_ADDR might solve " "your \n" -- cgit v1.2.3 From c70b7ffd80ee95cdf3bf1276bfbd4a590e74d3f1 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Tue, 8 Dec 2020 22:42:50 +0100 Subject: fix memory limit issue with cmplog without -m flag --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 269ce1bf..8a66018d 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -867,7 +867,7 @@ int main(int argc, char **argv_orig, char **envp) { } - if (!mem_limit_given && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260; + if (afl->fsrv.mem_limit && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260; OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" " "Eißfeldt, Andrea Fioraldi and Dominik Maier"); -- cgit v1.2.3 From 4e96447b43970acf8e43140aebdbccbe49dfd688 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 8 Dec 2020 23:26:08 +0100 Subject: fix showmap output --- src/afl-forkserver.c | 1 + src/afl-showmap.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 38cd529f..5a8e56b2 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -63,6 +63,7 @@ static void fsrv_exec_child(afl_forkserver_t *fsrv, char **argv) { execv(fsrv->target_path, argv); WARNF("Execv failed in forkserver."); + } /* Initializes the struct */ diff --git a/src/afl-showmap.c b/src/afl-showmap.c index e07e76c8..34a4f30d 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -287,6 +287,8 @@ static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, u8 *mem, afl_fsrv_write_to_testcase(fsrv, mem, len); + if (!quiet_mode) { SAYF("-- Program output begins --\n" cRST); } + if (afl_fsrv_run_target(fsrv, fsrv->exec_tmout, &stop_soon) == FSRV_RUN_ERROR) { @@ -711,6 +713,7 @@ int main(int argc, char **argv_orig, char **envp) { case 'C': collect_coverage = 1; + quiet_mode = 1; break; case 'i': @@ -817,7 +820,6 @@ int main(int argc, char **argv_orig, char **envp) { case 'q': - if (quiet_mode) { FATAL("Multiple -q options not supported"); } quiet_mode = 1; break; @@ -1189,7 +1191,7 @@ int main(int argc, char **argv_orig, char **envp) { } - if (!quiet_mode) { + if (!quiet_mode || collect_coverage) { if (!tcnt) { FATAL("No instrumentation detected" cRST); } OKF("Captured %u tuples (highest value %u, total values %llu) in " -- cgit v1.2.3 From a7125c68eb49d35de8aee6926cc0e9a9d839265f Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 8 Dec 2020 23:51:22 +0100 Subject: optimize a bit --- src/afl-sharedmem.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c index 6eb63949..cef908e0 100644 --- a/src/afl-sharedmem.c +++ b/src/afl-sharedmem.c @@ -248,22 +248,26 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, } - shm_str = alloc_printf("%d", shm->shm_id); + if (!non_instrumented_mode) { - /* If somebody is asking us to fuzz instrumented binaries in non-instrumented - mode, we don't want them to detect instrumentation, since we won't be - sending fork server commands. This should be replaced with better - auto-detection later on, perhaps? */ + shm_str = alloc_printf("%d", shm->shm_id); - if (!non_instrumented_mode) { setenv(SHM_ENV_VAR, shm_str, 1); } + /* If somebody is asking us to fuzz instrumented binaries in non-instrumented + mode, we don't want them to detect instrumentation, since we won't be + sending fork server commands. This should be replaced with better + auto-detection later on, perhaps? */ - ck_free(shm_str); + setenv(SHM_ENV_VAR, shm_str, 1); - if (shm->cmplog_mode) { + ck_free(shm_str); + + } + + if (shm->cmplog_mode && !non_instrumented_mode) { shm_str = alloc_printf("%d", shm->cmplog_shm_id); - if (!non_instrumented_mode) { setenv(CMPLOG_SHM_ENV_VAR, shm_str, 1); } + setenv(CMPLOG_SHM_ENV_VAR, shm_str, 1); ck_free(shm_str); @@ -274,6 +278,7 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, if (shm->map == (void *)-1 || !shm->map) { shmctl(shm->shm_id, IPC_RMID, NULL); // do not leak shmem + if (shm->cmplog_mode) { shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); // do not leak shmem @@ -291,11 +296,8 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, if (shm->cmp_map == (void *)-1 || !shm->cmp_map) { shmctl(shm->shm_id, IPC_RMID, NULL); // do not leak shmem - if (shm->cmplog_mode) { - - shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); // do not leak shmem - } + shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); // do not leak shmem PFATAL("shmat() failed"); -- cgit v1.2.3 From d1eb4eeb7fa3d94749dee4e8d625d242dbda1c1f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 9 Dec 2020 08:34:54 +0100 Subject: weighting for explore and exploit --- src/afl-fuzz-queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 071e4a4c..28d560d1 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -83,7 +83,7 @@ void create_alias_table(afl_state_t *afl) { memset((void *)afl->alias_table, 0, n * sizeof(u32)); memset((void *)afl->alias_probability, 0, n * sizeof(double)); - if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) { + if (likely(afl->schedule < RARE)) { double avg_exec_us = 0.0; double avg_bitmap_size = 0.0; -- cgit v1.2.3 From cebbedd238501d7f4326b0494cd60208a92e1645 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 9 Dec 2020 08:58:07 +0100 Subject: fix cmin/tmin potential overflow on too large files --- src/afl-forkserver.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 5a8e56b2..3afb94be 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -960,6 +960,8 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { if (fsrv->shmem_fuzz) { + if (unlikely(len > MAX_FILE)) len = MAX_FILE; + *fsrv->shmem_fuzz_len = len; memcpy(fsrv->shmem_fuzz, buf, len); #ifdef _DEBUG -- cgit v1.2.3 From 39a4fac941177387578ec856aacea2187588fc13 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 9 Dec 2020 11:07:14 +0100 Subject: better examples --- src/afl-sharedmem.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c index cef908e0..3e671df5 100644 --- a/src/afl-sharedmem.c +++ b/src/afl-sharedmem.c @@ -252,10 +252,10 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, shm_str = alloc_printf("%d", shm->shm_id); - /* If somebody is asking us to fuzz instrumented binaries in non-instrumented - mode, we don't want them to detect instrumentation, since we won't be - sending fork server commands. This should be replaced with better - auto-detection later on, perhaps? */ + /* If somebody is asking us to fuzz instrumented binaries in + non-instrumented mode, we don't want them to detect instrumentation, + since we won't be sending fork server commands. This should be replaced + with better auto-detection later on, perhaps? */ setenv(SHM_ENV_VAR, shm_str, 1); -- cgit v1.2.3 From e5c50037d5029e995c057ae50ece6b1ee87db106 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 9 Dec 2020 12:03:11 +0100 Subject: fix oversight for accessing nfuzz --- src/afl-fuzz-queue.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 28d560d1..84092ff8 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -45,8 +45,15 @@ inline u32 select_next_queue_entry(afl_state_t *afl) { double compute_weight(afl_state_t *afl, struct queue_entry *q, double avg_exec_us, double avg_bitmap_size) { - u32 hits = afl->n_fuzz[q->n_fuzz_entry]; - if (hits == 0) hits = 1; + u32 hits; + + if (likely(afl->schedule >= FAST && afl->schedule < RARE)) { + + hits = afl->n_fuzz[q->n_fuzz_entry]; + if (hits == 0) { hits = 1; } + + } else { hits = 1; } + double weight = 1.0; weight *= avg_exec_us / q->exec_us; -- cgit v1.2.3 From a686c1361ce353c6f47939eb7af1f264f0ce4853 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 10 Dec 2020 15:31:26 +0100 Subject: fix afl-cc library search --- src/afl-cc.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 273a9f2f..14d8e070 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -130,20 +130,27 @@ static u8 *find_object(u8 *obj, u8 *argv0) { u8 *afl_path = getenv("AFL_PATH"); u8 *slash = NULL, *tmp; - if (obj_path) { + /* + if (obj_path) { - tmp = alloc_printf("%s/%s", obj_path, obj); + tmp = alloc_printf("%s/%s", obj_path, obj); - if (!access(tmp, R_OK)) { return tmp; } + if (debug) DEBUGF("Trying %s\n", tmp); - ck_free(tmp); + if (!access(tmp, R_OK)) { return tmp; } - } + ck_free(tmp); + + } + + */ if (afl_path) { tmp = alloc_printf("%s/%s", afl_path, obj); + if (debug) DEBUGF("Trying %s\n", tmp); + if (!access(tmp, R_OK)) { obj_path = afl_path; @@ -168,6 +175,8 @@ static u8 *find_object(u8 *obj, u8 *argv0) { tmp = alloc_printf("%s/%s", dir, obj); + if (debug) DEBUGF("Trying %s\n", tmp); + if (!access(tmp, R_OK)) { obj_path = dir; @@ -178,6 +187,8 @@ static u8 *find_object(u8 *obj, u8 *argv0) { ck_free(tmp); tmp = alloc_printf("%s/../lib/afl/%s", dir, obj); + if (debug) DEBUGF("Trying %s\n", tmp); + if (!access(tmp, R_OK)) { u8 *dir2 = alloc_printf("%s/../lib/afl", dir); @@ -232,6 +243,8 @@ static u8 *find_object(u8 *obj, u8 *argv0) { ck_free(tmp); tmp = alloc_printf("%s/../lib/afl/%s", exepath, obj); + if (debug) DEBUGF("Trying %s\n", tmp); + if (!access(tmp, R_OK)) { u8 *dir = alloc_printf("%s/../lib/afl/", exepath); @@ -255,6 +268,8 @@ static u8 *find_object(u8 *obj, u8 *argv0) { tmp = alloc_printf("%s/%s", AFL_PATH, obj); + if (debug) DEBUGF("Trying %s\n", tmp); + if (!access(tmp, R_OK)) { obj_path = AFL_PATH; @@ -266,6 +281,8 @@ static u8 *find_object(u8 *obj, u8 *argv0) { tmp = alloc_printf("./%s", obj); + if (debug) DEBUGF("Trying %s\n", tmp); + if (!access(tmp, R_OK)) { obj_path = "."; @@ -275,6 +292,8 @@ static u8 *find_object(u8 *obj, u8 *argv0) { ck_free(tmp); + if (debug) DEBUGF("Trying ... giving up\n"); + return NULL; } -- cgit v1.2.3 From 8a1acac559edb66e8e246e73508cec541a9fc530 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 11 Dec 2020 10:28:39 +0100 Subject: schedule improvements, new default is FAST --- src/afl-fuzz-queue.c | 2 +- src/afl-fuzz-state.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 84092ff8..d74c07a1 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -47,7 +47,7 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q, u32 hits; - if (likely(afl->schedule >= FAST && afl->schedule < RARE)) { + if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) { hits = afl->n_fuzz[q->n_fuzz_entry]; if (hits == 0) { hits = 1; } diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 73b94466..36da2730 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -87,7 +87,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->w_end = 0.3; afl->g_max = 5000; afl->period_pilot_tmp = 5000.0; - afl->schedule = EXPLORE; /* Power schedule (default: EXPLORE) */ + afl->schedule = FAST ; /* Power schedule (default: FAST) */ afl->havoc_max_mult = HAVOC_MAX_MULT; afl->clear_screen = 1; /* Window resized? */ -- cgit v1.2.3 From 2bf68a0bf45fb2bb3bc0f574f20959a62c9f8239 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 11 Dec 2020 11:19:26 +0100 Subject: fix MMAP --- src/afl-cc.c | 27 +++++++++++---------------- src/afl-fuzz.c | 8 +++++++- 2 files changed, 18 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 14d8e070..37cfc7c8 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -130,21 +130,6 @@ static u8 *find_object(u8 *obj, u8 *argv0) { u8 *afl_path = getenv("AFL_PATH"); u8 *slash = NULL, *tmp; - /* - if (obj_path) { - - tmp = alloc_printf("%s/%s", obj_path, obj); - - if (debug) DEBUGF("Trying %s\n", tmp); - - if (!access(tmp, R_OK)) { return tmp; } - - ck_free(tmp); - - } - - */ - if (afl_path) { tmp = alloc_printf("%s/%s", afl_path, obj); @@ -906,6 +891,10 @@ static void edit_params(u32 argc, char **argv, char **envp) { alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); #endif +#ifdef USEMMAP + cc_params[cc_par_cnt++] = "-lrt"; +#endif + } #endif @@ -1475,9 +1464,15 @@ int main(int argc, char **argv, char **envp) { if (have_llvm) SAYF("afl-cc LLVM version %d with the the binary path \"%s\".\n", LLVM_MAJOR, LLVM_BINDIR); - if (have_lto || have_llvm) SAYF("\n"); #endif +#ifdef USEMMAP + SAYF("Compiled with shm_open support (adds -lrt when linking).\n"); +#else + SAYF("Compiled with shmat support.\n"); +#endif + SAYF("\n"); + SAYF( "Do not be overwhelmed :) afl-cc uses good defaults if no options are " "selected.\n" diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index bbe6aec6..391d4c4f 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -230,6 +230,12 @@ static void usage(u8 *argv0, int more_help) { SAYF("Compiled without python module support\n"); #endif +#ifdef USEMMAP + SAYF("Compiled with shm_open support.\n"); +#else + SAYF("Compiled with shmat support.\n"); +#endif + #ifdef ASAN_BUILD SAYF("Compiled with ASAN_BUILD\n\n"); #endif @@ -254,7 +260,7 @@ static void usage(u8 *argv0, int more_help) { SAYF("Compiled with _AFL_DOCUMENT_MUTATIONS\n\n"); #endif - SAYF("For additional help please consult %s/README.md\n\n", doc_path); + SAYF("For additional help please consult %s/README.md :)\n\n", doc_path); exit(1); #undef PHYTON_SUPPORT -- cgit v1.2.3 From cc781e44f36d716f05da13bf760154a7810bfe43 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 11 Dec 2020 11:21:28 +0100 Subject: code format --- src/afl-cc.c | 8 ++++---- src/afl-fuzz-queue.c | 13 ++++++++----- src/afl-fuzz-state.c | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 37cfc7c8..c43ac2c1 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -891,9 +891,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); #endif -#ifdef USEMMAP + #ifdef USEMMAP cc_params[cc_par_cnt++] = "-lrt"; -#endif + #endif } @@ -1467,9 +1467,9 @@ int main(int argc, char **argv, char **envp) { #endif #ifdef USEMMAP - SAYF("Compiled with shm_open support (adds -lrt when linking).\n"); + SAYF("Compiled with shm_open support (adds -lrt when linking).\n"); #else - SAYF("Compiled with shmat support.\n"); + SAYF("Compiled with shmat support.\n"); #endif SAYF("\n"); diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index d74c07a1..54afa17c 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -46,14 +46,17 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q, double avg_exec_us, double avg_bitmap_size) { u32 hits; - + if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) { - + hits = afl->n_fuzz[q->n_fuzz_entry]; if (hits == 0) { hits = 1; } - - } else { hits = 1; } - + + } else { + + hits = 1; + + } double weight = 1.0; weight *= avg_exec_us / q->exec_us; diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 36da2730..9c51a3ef 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -87,7 +87,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->w_end = 0.3; afl->g_max = 5000; afl->period_pilot_tmp = 5000.0; - afl->schedule = FAST ; /* Power schedule (default: FAST) */ + afl->schedule = FAST; /* Power schedule (default: FAST) */ afl->havoc_max_mult = HAVOC_MAX_MULT; afl->clear_screen = 1; /* Window resized? */ -- cgit v1.2.3 From 609f3d02651381215815eeadb7a10999c2041ffe Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 11 Dec 2020 13:29:45 +0100 Subject: fixed gcc analyzer warnings --- src/afl-as.c | 5 +++++ src/afl-common.c | 24 ++++++++++++++++++++++-- src/afl-fuzz-init.c | 18 +++++++++++++----- src/afl-fuzz-run.c | 12 ++++++------ 4 files changed, 46 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/afl-as.c b/src/afl-as.c index 3d6f7d5e..2171bb58 100644 --- a/src/afl-as.c +++ b/src/afl-as.c @@ -131,6 +131,11 @@ static void edit_params(int argc, char **argv) { if (!tmp_dir) { tmp_dir = "/tmp"; } as_params = ck_alloc((argc + 32) * sizeof(u8 *)); + if (unlikely((argc + 32) < argc || !as_params)) { + + FATAL("Too many parameters passed to as"); + + } as_params[0] = afl_as ? afl_as : (u8 *)"as"; diff --git a/src/afl-common.c b/src/afl-common.c index ed0b0e53..4df22394 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -108,6 +108,7 @@ char **argv_cpy_dup(int argc, char **argv) { int i = 0; char **ret = ck_alloc((argc + 1) * sizeof(char *)); + if (unlikely(!ret)) { FATAL("Amount of arguments specified is too high"); } for (i = 0; i < argc; i++) { @@ -130,6 +131,7 @@ void argv_cpy_free(char **argv) { while (argv[i]) { ck_free(argv[i]); + argv[i] = NULL; i++; } @@ -142,8 +144,12 @@ void argv_cpy_free(char **argv) { char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { + if (!unlikely(own_loc)) { FATAL("BUG: param own_loc is NULL"); } + + u8 *tmp, *cp = NULL, *rsl, *own_copy; + char **new_argv = ck_alloc(sizeof(char *) * (argc + 4)); - u8 * tmp, *cp = NULL, *rsl, *own_copy; + if (unlikely(!new_argv)) { FATAL("Illegal amount of arguments specified"); } memcpy(&new_argv[3], &argv[1], (int)(sizeof(char *)) * (argc - 1)); new_argv[argc + 3] = NULL; @@ -224,8 +230,12 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { + if (!unlikely(own_loc)) { FATAL("BUG: param own_loc is NULL"); } + + u8 *tmp, *cp = NULL, *rsl, *own_copy; + char **new_argv = ck_alloc(sizeof(char *) * (argc + 3)); - u8 * tmp, *cp = NULL, *rsl, *own_copy; + if (unlikely(!new_argv)) { FATAL("Illegal amount of arguments specified"); } memcpy(&new_argv[2], &argv[1], (int)(sizeof(char *)) * (argc - 1)); new_argv[argc + 2] = NULL; @@ -335,6 +345,8 @@ u8 *find_binary(u8 *fname) { struct stat st; + if (unlikely(!fname)) { FATAL("No binary supplied"); } + if (strchr(fname, '/') || !(env_path = getenv("PATH"))) { target_path = ck_strdup(fname); @@ -356,6 +368,14 @@ u8 *find_binary(u8 *fname) { if (delim) { cur_elem = ck_alloc(delim - env_path + 1); + if (unlikely(!cur_elem)) { + + FATAL( + "Unexpected overflow when processing ENV. This should never " + "happend."); + + } + memcpy(cur_elem, env_path, delim - env_path); delim++; diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 6707340b..0db3a111 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -772,10 +772,17 @@ void perform_dry_run(afl_state_t *afl) { while (q) { - u8 *use_mem; + u8 use_mem[MAX_FILE]; u8 res; s32 fd; + if (unlikely(!q->len)) { + + WARNF("Skipping 0-sized entry in queue (%s)", q->fname); + continue; + + } + u8 *fn = strrchr(q->fname, '/') + 1; ACTF("Attempting dry run with '%s'...", fn); @@ -783,9 +790,8 @@ void perform_dry_run(afl_state_t *afl) { fd = open(q->fname, O_RDONLY); if (fd < 0) { PFATAL("Unable to open '%s'", q->fname); } - use_mem = ck_alloc_nozero(q->len); - - if (read(fd, use_mem, q->len) != (ssize_t)q->len) { + u32 read_len = MIN(q->len, (u32)MAX_FILE); + if (read(fd, use_mem, read_len) != (ssize_t)read_len) { FATAL("Short read from '%s'", q->fname); @@ -794,7 +800,6 @@ void perform_dry_run(afl_state_t *afl) { close(fd); res = calibrate_case(afl, q, use_mem, 0, 1); - ck_free(use_mem); if (afl->stop_soon) { return; } @@ -2449,6 +2454,8 @@ void setup_testcase_shmem(afl_state_t *afl) { void check_binary(afl_state_t *afl, u8 *fname) { + if (unlikely(!fname)) { FATAL("BUG: Binary name is NULL"); } + u8 * env_path = 0; struct stat st; @@ -2477,6 +2484,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { if (delim) { cur_elem = ck_alloc(delim - env_path + 1); + if (unlikely(!cur_elem)) { FATAL("Unexpected large PATH"); } memcpy(cur_elem, env_path, delim - env_path); ++delim; diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 5948d83a..b6603f1a 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -94,9 +94,9 @@ write_to_testcase(afl_state_t *afl, void *mem, u32 len) { if (unlikely(afl->custom_mutators_count)) { - u8 * new_buf = NULL; ssize_t new_size = len; - void * new_mem = mem; + u8 * new_mem = mem; + u8 * new_buf = NULL; LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { @@ -152,13 +152,13 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at, if (unlikely(!mem_trimmed)) { PFATAL("alloc"); } ssize_t new_size = len - skip_len; - void * new_mem = mem; - u8 * new_buf = NULL; + u8 * new_mem = mem; bool post_process_skipped = true; if (unlikely(afl->custom_mutators_count)) { + u8 *new_buf = NULL; new_mem = mem_trimmed; LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { @@ -207,7 +207,7 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at, // If we did post_processing, copy directly from the new_buf bufer - memcpy(afl->fsrv.shmem_fuzz, new_buf, new_size); + memcpy(afl->fsrv.shmem_fuzz, new_mem, new_size); } @@ -265,7 +265,7 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at, if (!post_process_skipped) { - ck_write(fd, new_buf, new_size, afl->fsrv.out_file); + ck_write(fd, new_mem, new_size, afl->fsrv.out_file); } else { -- cgit v1.2.3 From e4a113b953e0b746cffa47e24ad52f18733217bc Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 12 Dec 2020 13:26:25 +0100 Subject: small fix in error handling --- src/afl-sharedmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c index 3e671df5..fe641d0d 100644 --- a/src/afl-sharedmem.c +++ b/src/afl-sharedmem.c @@ -205,7 +205,7 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, /* map the shared memory segment to the address space of the process */ shm->cmp_map = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm->cmplog_g_shm_fd, 0); - if (shm->map == MAP_FAILED) { + if (shm->cmp_map == MAP_FAILED) { close(shm->cmplog_g_shm_fd); shm->cmplog_g_shm_fd = -1; -- cgit v1.2.3 From fd30a4184a149cfd1f45ff6de94487dbdc6dea61 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 12 Dec 2020 16:37:23 +0100 Subject: typo --- src/afl-fuzz-run.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index b6603f1a..c8ad14c4 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -205,7 +205,7 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at, if (!post_process_skipped) { - // If we did post_processing, copy directly from the new_buf bufer + // If we did post_processing, copy directly from the new_mem buffer memcpy(afl->fsrv.shmem_fuzz, new_mem, new_size); @@ -365,7 +365,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, write_to_testcase(afl, use_mem, q->len); fault = fuzz_run_target(afl, &afl->fsrv, use_tmout); - +fprintf(stderr, "from fuzz_run_target() fault=%u\n", fault); /* afl->stop_soon is set by the handler for Ctrl+C. When it's pressed, we want to bail out quickly. */ -- cgit v1.2.3 From befb1a2f39b28dbc360d5a6937705c48768ec053 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 12 Dec 2020 16:40:13 +0100 Subject: remove stray debugging fprintf --- src/afl-fuzz-run.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index c8ad14c4..a97ceb89 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -365,7 +365,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, write_to_testcase(afl, use_mem, q->len); fault = fuzz_run_target(afl, &afl->fsrv, use_tmout); -fprintf(stderr, "from fuzz_run_target() fault=%u\n", fault); + /* afl->stop_soon is set by the handler for Ctrl+C. When it's pressed, we want to bail out quickly. */ -- cgit v1.2.3 From 7382cf5f00c1ba5d926c12e3ed4ca0e14d761fcb Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 12 Dec 2020 19:30:56 +0100 Subject: afl-as.c, fix compiler warnings (overflowing is UB) --- src/afl-as.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-as.c b/src/afl-as.c index 2171bb58..7de267a3 100644 --- a/src/afl-as.c +++ b/src/afl-as.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -131,7 +132,7 @@ static void edit_params(int argc, char **argv) { if (!tmp_dir) { tmp_dir = "/tmp"; } as_params = ck_alloc((argc + 32) * sizeof(u8 *)); - if (unlikely((argc + 32) < argc || !as_params)) { + if (unlikely((INT_MAX - 32) < argc || !as_params)) { FATAL("Too many parameters passed to as"); -- cgit v1.2.3 From e0ab846f7fd3e45bbf76e4ab82eef19d9aaf5494 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 15 Dec 2020 09:37:52 +0100 Subject: v3.00c --- src/afl-cc.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index c43ac2c1..2aeb2178 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -69,6 +69,7 @@ enum { INSTRUMENT_INSTRIM = 3, INSTRUMENT_CFG = 3, INSTRUMENT_LTO = 4, + INSTRUMENT_LLVMNATIVE = 5, INSTRUMENT_OPT_CTX = 8, INSTRUMENT_OPT_NGRAM = 16 @@ -76,8 +77,9 @@ enum { char instrument_mode_string[18][18] = { - "DEFAULT", "CLASSIC", "PCGUARD", "CFG", "LTO", "", "", "", "CTX", "", - "", "", "", "", "", "", "NGRAM", "" + "DEFAULT", "CLASSIC", "PCGUARD", "CFG", "LTO", "", "PCGUARD-NATIVE", + "", "CTX", "", "", "", "", "", + "", "", "NGRAM", "" }; @@ -580,6 +582,14 @@ static void edit_params(u32 argc, char **argv, char **envp) { #endif #endif + } else if (instrument_mode == INSTRUMENT_LLVMNATIVE) { + +#if LLVM_MAJOR >= 4 + cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; +#else + FATAL("pcguard instrumentation requires llvm 4.0.1+"); +#endif + } else { cc_params[cc_par_cnt++] = "-Xclang"; @@ -1162,6 +1172,18 @@ int main(int argc, char **argv, char **envp) { } + // this is a hidden option + if (strncasecmp(ptr, "llvmnative", strlen("llvmnative")) == 0 || + strncasecmp(ptr, "llvm-native", strlen("llvm-native")) == 0) { + + if (!instrument_mode || instrument_mode == INSTRUMENT_LLVMNATIVE) + instrument_mode = INSTRUMENT_LLVMNATIVE; + else + FATAL("main instrumentation mode already set with %s", + instrument_mode_string[instrument_mode]); + + } + if (strncasecmp(ptr, "cfg", strlen("cfg")) == 0 || strncasecmp(ptr, "instrim", strlen("instrim")) == 0) { -- cgit v1.2.3 From 14c67f15c98b16bb0c22f6a94d66d714bf61af5a Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 16 Dec 2020 14:22:09 +0100 Subject: small fixes --- src/afl-fuzz-init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 0db3a111..ec937f29 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -666,7 +666,7 @@ void read_testcases(afl_state_t *afl, u8 *directory) { } - if (afl->shuffle_queue && nl_cnt > 1) { + if (unlikely(afl->old_seed_selection && afl->shuffle_queue && nl_cnt > 1)) { ACTF("Shuffling queue..."); shuffle_ptrs(afl, (void **)nl, nl_cnt); -- cgit v1.2.3 From d07b0169cb6137e4620db63b144e46e140b7437d Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 17 Dec 2020 10:55:33 +0100 Subject: skim import --- src/afl-fuzz-bitmap.c | 284 ++++++++++++++------------------------------------ src/afl-fuzz-run.c | 6 +- 2 files changed, 82 insertions(+), 208 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index f1ca7400..738ba986 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -49,101 +49,6 @@ void write_bitmap(afl_state_t *afl) { } -/* Check if the current execution path brings anything new to the table. - Update virgin bits to reflect the finds. Returns 1 if the only change is - the hit-count for a particular tuple; 2 if there are new tuples seen. - Updates the map, so subsequent calls will always return 0. - - This function is called after every exec() on a fairly large buffer, so - it needs to be fast. We do this in 32-bit and 64-bit flavors. */ - -u8 __attribute__((hot)) has_new_bits(afl_state_t *afl, u8 *virgin_map) { - -#ifdef WORD_SIZE_64 - - u64 *current = (u64 *)afl->fsrv.trace_bits; - u64 *virgin = (u64 *)virgin_map; - - u32 i = (afl->fsrv.map_size >> 3); - -#else - - u32 *current = (u32 *)afl->fsrv.trace_bits; - u32 *virgin = (u32 *)virgin_map; - - u32 i = (afl->fsrv.map_size >> 2); - -#endif /* ^WORD_SIZE_64 */ - // the map size must be a minimum of 8 bytes. - // for variable/dynamic map sizes this is ensured in the forkserver - - u8 ret = 0; - - while (i--) { - - /* Optimize for (*current & *virgin) == 0 - i.e., no bits in current bitmap - that have not been already cleared from the virgin map - since this will - almost always be the case. */ - - // the (*current) is unnecessary but speeds up the overall comparison - if (unlikely(*current) && unlikely(*current & *virgin)) { - - if (likely(ret < 2)) { - - u8 *cur = (u8 *)current; - u8 *vir = (u8 *)virgin; - - /* Looks like we have not found any new bytes yet; see if any non-zero - bytes in current[] are pristine in virgin[]. */ - -#ifdef WORD_SIZE_64 - - if (*virgin == 0xffffffffffffffff || (cur[0] && vir[0] == 0xff) || - (cur[1] && vir[1] == 0xff) || (cur[2] && vir[2] == 0xff) || - (cur[3] && vir[3] == 0xff) || (cur[4] && vir[4] == 0xff) || - (cur[5] && vir[5] == 0xff) || (cur[6] && vir[6] == 0xff) || - (cur[7] && vir[7] == 0xff)) { - - ret = 2; - - } else { - - ret = 1; - - } - -#else - - if (*virgin == 0xffffffff || (cur[0] && vir[0] == 0xff) || - (cur[1] && vir[1] == 0xff) || (cur[2] && vir[2] == 0xff) || - (cur[3] && vir[3] == 0xff)) - ret = 2; - else - ret = 1; - -#endif /* ^WORD_SIZE_64 */ - - } - - *virgin &= ~*current; - - } - - ++current; - ++virgin; - - } - - if (unlikely(ret) && likely(virgin_map == afl->virgin_bits)) { - - afl->bitmap_changed = 1; - - } - - return ret; - -} - /* Count the number of bits set in the provided bitmap. Used for the status screen several times every second, does not have to be fast. */ @@ -242,77 +147,11 @@ const u8 simplify_lookup[256] = { }; -#ifdef WORD_SIZE_64 - -void simplify_trace(afl_state_t *afl, u64 *mem) { - - u32 i = (afl->fsrv.map_size >> 3); - - while (i--) { - - /* Optimize for sparse bitmaps. */ - - if (unlikely(*mem)) { - - u8 *mem8 = (u8 *)mem; - - mem8[0] = simplify_lookup[mem8[0]]; - mem8[1] = simplify_lookup[mem8[1]]; - mem8[2] = simplify_lookup[mem8[2]]; - mem8[3] = simplify_lookup[mem8[3]]; - mem8[4] = simplify_lookup[mem8[4]]; - mem8[5] = simplify_lookup[mem8[5]]; - mem8[6] = simplify_lookup[mem8[6]]; - mem8[7] = simplify_lookup[mem8[7]]; - - } else { - - *mem = 0x0101010101010101ULL; - - } - - ++mem; - - } - -} - -#else - -void simplify_trace(afl_state_t *afl, u32 *mem) { - - u32 i = (afl->fsrv.map_size >> 2); - - while (i--) { - - /* Optimize for sparse bitmaps. */ - - if (unlikely(*mem)) { - - u8 *mem8 = (u8 *)mem; - - mem8[0] = simplify_lookup[mem8[0]]; - mem8[1] = simplify_lookup[mem8[1]]; - mem8[2] = simplify_lookup[mem8[2]]; - mem8[3] = simplify_lookup[mem8[3]]; - - } else - - *mem = 0x01010101; - - ++mem; - - } - -} - -#endif /* ^WORD_SIZE_64 */ - /* Destructively classify execution counts in a trace. This is used as a preprocessing step for any newly acquired traces. Called on every exec, must be fast. */ -static const u8 count_class_lookup8[256] = { +const u8 count_class_lookup8[256] = { [0] = 0, [1] = 1, @@ -326,7 +165,7 @@ static const u8 count_class_lookup8[256] = { }; -static u16 count_class_lookup16[65536]; +u16 count_class_lookup16[65536]; void init_count_class16(void) { @@ -345,63 +184,87 @@ void init_count_class16(void) { } -#ifdef WORD_SIZE_64 +/* Import coverage processing routines. */ -void __attribute__((hot)) classify_counts(afl_forkserver_t *fsrv) { +#ifdef WORD_SIZE_64 + #include "coverage-64.h" +#else + #include "coverage-32.h" +#endif - u64 *mem = (u64 *)fsrv->trace_bits; +/* Check if the current execution path brings anything new to the table. + Update virgin bits to reflect the finds. Returns 1 if the only change is + the hit-count for a particular tuple; 2 if there are new tuples seen. + Updates the map, so subsequent calls will always return 0. - u32 i = (fsrv->map_size >> 3); + This function is called after every exec() on a fairly large buffer, so + it needs to be fast. We do this in 32-bit and 64-bit flavors. */ - while (i--) { +inline u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) { - /* Optimize for sparse bitmaps. */ +#ifdef WORD_SIZE_64 - if (unlikely(*mem)) { + u64 *current = (u64 *)afl->fsrv.trace_bits; + u64 *virgin = (u64 *)virgin_map; - u16 *mem16 = (u16 *)mem; + u32 i = (afl->fsrv.map_size >> 3); - mem16[0] = count_class_lookup16[mem16[0]]; - mem16[1] = count_class_lookup16[mem16[1]]; - mem16[2] = count_class_lookup16[mem16[2]]; - mem16[3] = count_class_lookup16[mem16[3]]; +#else - } + u32 *current = (u32 *)afl->fsrv.trace_bits; + u32 *virgin = (u32 *)virgin_map; - ++mem; + u32 i = (afl->fsrv.map_size >> 2); - } +#endif /* ^WORD_SIZE_64 */ -} + u8 ret = 0; + while (i--) { -#else + if (unlikely(*current)) discover_word(&ret, current, virgin); -void __attribute__((hot)) classify_counts(afl_forkserver_t *fsrv) { + current++; + virgin++; - u32 *mem = (u32 *)fsrv->trace_bits; + } - u32 i = (fsrv->map_size >> 2); + if (unlikely(ret) && likely(virgin_map == afl->virgin_bits)) + afl->bitmap_changed = 1; - while (i--) { + return ret; - /* Optimize for sparse bitmaps. */ +} - if (unlikely(*mem)) { +/* A combination of classify_counts and has_new_bits. If 0 is returned, then the + * trace bits are kept as-is. Otherwise, the trace bits are overwritten with + * classified values. + * + * This accelerates the processing: in most cases, no interesting behavior + * happen, and the trace bits will be discarded soon. This function optimizes + * for such cases: one-pass scan on trace bits without modifying anything. Only + * on rare cases it fall backs to the slow path: classify_counts() first, then + * return has_new_bits(). */ - u16 *mem16 = (u16 *)mem; +inline u8 has_new_bits_unclassified(afl_state_t *afl, u8 *virgin_map) { - mem16[0] = count_class_lookup16[mem16[0]]; - mem16[1] = count_class_lookup16[mem16[1]]; + /* Handle the hot path first: no new coverage */ + u8 *end = afl->fsrv.trace_bits + afl->fsrv.map_size; - } +#ifdef WORD_SIZE_64 - ++mem; + if (!skim((u64 *)virgin_map, (u64 *)afl->fsrv.trace_bits, (u64 *)end)) + return 0; - } +#else -} + if (!skim((u32 *)virgin_map, (u32 *)afl->fsrv.trace_bits, (u32 *)end)) + return 0; #endif /* ^WORD_SIZE_64 */ + classify_counts(&afl->fsrv); + return has_new_bits(afl, virgin_map); + +} /* Compact trace bytes into a smaller bitmap. We effectively just drop the count information here. This is called only sporadically, for some @@ -581,7 +444,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { u8 *queue_fn = ""; u8 new_bits = '\0'; s32 fd; - u8 keeping = 0, res; + u8 keeping = 0, res, classified = 0; u64 cksum = 0; u8 fn[PATH_MAX]; @@ -605,13 +468,17 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { /* Keep only if there are new bits in the map, add to queue for future fuzzing, etc. */ - if (!(new_bits = has_new_bits(afl, afl->virgin_bits))) { + new_bits = has_new_bits_unclassified(afl, afl->virgin_bits); + + if (likely(!new_bits)) { if (unlikely(afl->crash_mode)) { ++afl->total_crashes; } return 0; } + classified = new_bits; + #ifndef SIMPLE_FILES queue_fn = alloc_printf( @@ -715,11 +582,14 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (likely(!afl->non_instrumented_mode)) { -#ifdef WORD_SIZE_64 - simplify_trace(afl, (u64 *)afl->fsrv.trace_bits); -#else - simplify_trace(afl, (u32 *)afl->fsrv.trace_bits); -#endif /* ^WORD_SIZE_64 */ + if (!classified) { + + classify_counts(&afl->fsrv); + classified = 1; + + } + + simplify_trace(afl, afl->fsrv.trace_bits); if (!has_new_bits(afl, afl->virgin_tmout)) { return keeping; } @@ -764,6 +634,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { u8 new_fault; write_to_testcase(afl, mem, len); new_fault = fuzz_run_target(afl, &afl->fsrv, afl->hang_tmout); + classify_counts(&afl->fsrv); /* A corner case that one user reported bumping into: increasing the timeout actually uncovers a crash. Make sure we don't discard it if @@ -812,11 +683,14 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (likely(!afl->non_instrumented_mode)) { -#ifdef WORD_SIZE_64 - simplify_trace(afl, (u64 *)afl->fsrv.trace_bits); -#else - simplify_trace(afl, (u32 *)afl->fsrv.trace_bits); -#endif /* ^WORD_SIZE_64 */ + if (!classified) { + + classify_counts(&afl->fsrv); + classified = 1; + + } + + simplify_trace(afl, afl->fsrv.trace_bits); if (!has_new_bits(afl, afl->virgin_crash)) { return keeping; } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index a97ceb89..60086bd6 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -62,8 +62,6 @@ fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, u32 timeout) { time_spent_start = (spec.tv_sec * 1000000000) + spec.tv_nsec; #endif - // TODO: Don't classify for faults? - classify_counts(fsrv); return res; } @@ -379,6 +377,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, } + classify_counts(&afl->fsrv); cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); if (q->exec_cksum != cksum) { @@ -767,13 +766,14 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { write_with_gap(afl, in_buf, q->len, remove_pos, trim_avail); fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); - ++afl->trim_execs; if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; } /* Note that we don't keep track of crashes or hangs here; maybe TODO? */ + ++afl->trim_execs; + classify_counts(&afl->fsrv); cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); /* If the deletion had no impact on the trace, make it permanent. This -- cgit v1.2.3 From fd6bff727a860220bdd035952a7666c60f444b3f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 17 Dec 2020 22:57:28 +0100 Subject: fix crash for very fast targets --- src/afl-common.c | 5 +++++ src/afl-fuzz-stats.c | 2 ++ 2 files changed, 7 insertions(+) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 4df22394..6dc8abe0 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "debug.h" #include "alloc-inl.h" @@ -786,6 +787,10 @@ u8 *u_stringify_float(u8 *buf, double val) { sprintf(buf, "%0.01f", val); + } else if (unlikely(isnan(val) || isfinite(val))) { + + strcpy(buf, "999.9"); + } else { return u_stringify_int(buf, (u64)val); diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 321bbb35..50e2ef15 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -371,6 +371,8 @@ void show_stats(afl_state_t *afl) { if (!afl->stats_last_execs) { + if (unlikely(cur_ms == afl->start_time)) --afl->start_time; + afl->stats_avg_exec = ((double)afl->fsrv.total_execs) * 1000 / (cur_ms - afl->start_time); -- cgit v1.2.3 From 0011f2047bdd3e1adc25de4388edd609dc27bc85 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 18 Dec 2020 09:33:52 +0100 Subject: merge romu and skim --- src/afl-performance.c | 124 +++++++++++--------------------------------------- 1 file changed, 27 insertions(+), 97 deletions(-) (limited to 'src') diff --git a/src/afl-performance.c b/src/afl-performance.c index e070a05e..89b170eb 100644 --- a/src/afl-performance.c +++ b/src/afl-performance.c @@ -27,45 +27,49 @@ #include "xxhash.h" #undef XXH_INLINE_ALL -/* we use xoshiro256** instead of rand/random because it is 10x faster and has - better randomness properties. */ - -static inline uint64_t rotl(const uint64_t x, int k) { - - return (x << k) | (x >> (64 - k)); - -} - void rand_set_seed(afl_state_t *afl, s64 init_seed) { afl->init_seed = init_seed; afl->rand_seed[0] = hash64((u8 *)&afl->init_seed, sizeof(afl->init_seed), HASH_CONST); afl->rand_seed[1] = afl->rand_seed[0] ^ 0x1234567890abcdef; - afl->rand_seed[2] = afl->rand_seed[0] & 0x0123456789abcdef; - afl->rand_seed[3] = afl->rand_seed[0] | 0x01abcde43f567908; + afl->rand_seed[2] = (afl->rand_seed[0] & 0x1234567890abcdef) ^ + (afl->rand_seed[1] | 0xfedcba9876543210); } -inline uint64_t rand_next(afl_state_t *afl) { +#define ROTL(d, lrot) ((d << (lrot)) | (d >> (8 * sizeof(d) - (lrot)))) - const uint64_t result = - rotl(afl->rand_seed[0] + afl->rand_seed[3], 23) + afl->rand_seed[0]; +#ifdef WORD_SIZE_64 +// romuDuoJr +inline AFL_RAND_RETURN rand_next(afl_state_t *afl) { - const uint64_t t = afl->rand_seed[1] << 17; + AFL_RAND_RETURN xp = afl->rand_seed[0]; + afl->rand_seed[0] = 15241094284759029579u * afl->rand_seed[1]; + afl->rand_seed[1] = afl->rand_seed[1] - xp; + afl->rand_seed[1] = ROTL(afl->rand_seed[1], 27); + return xp; - afl->rand_seed[2] ^= afl->rand_seed[0]; - afl->rand_seed[3] ^= afl->rand_seed[1]; - afl->rand_seed[1] ^= afl->rand_seed[2]; - afl->rand_seed[0] ^= afl->rand_seed[3]; +} - afl->rand_seed[2] ^= t; +#else +// RomuTrio32 +inline AFL_RAND_RETURN rand_next(afl_state_t *afl) { + + AFL_RAND_RETURN xp = afl->rand_seed[0], yp = afl->rand_seed[1], + zp = afl->rand_seed[2]; + afl->rand_seed[0] = 3323815723u * zp; + afl->rand_seed[1] = yp - xp; + afl->rand_seed[1] = ROTL(afl->rand_seed[1], 6); + afl->rand_seed[2] = zp - yp; + afl->rand_seed[2] = ROTL(afl->rand_seed[2], 22); + return xp; - afl->rand_seed[3] = rotl(afl->rand_seed[3], 45); +} - return result; +#endif -} +#undef ROTL /* returns a double between 0.000000000 and 1.000000000 */ @@ -75,80 +79,6 @@ inline double rand_next_percent(afl_state_t *afl) { } -/* This is the jump function for the generator. It is equivalent - to 2^128 calls to rand_next(); it can be used to generate 2^128 - non-overlapping subsequences for parallel computations. */ - -void jump(afl_state_t *afl) { - - static const uint64_t JUMP[] = {0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, - 0xa9582618e03fc9aa, 0x39abdc4529b1661c}; - size_t i, b; - uint64_t s0 = 0; - uint64_t s1 = 0; - uint64_t s2 = 0; - uint64_t s3 = 0; - for (i = 0; i < (sizeof(JUMP) / sizeof(*JUMP)); i++) - for (b = 0; b < 64; b++) { - - if (JUMP[i] & UINT64_C(1) << b) { - - s0 ^= afl->rand_seed[0]; - s1 ^= afl->rand_seed[1]; - s2 ^= afl->rand_seed[2]; - s3 ^= afl->rand_seed[3]; - - } - - rand_next(afl); - - } - - afl->rand_seed[0] = s0; - afl->rand_seed[1] = s1; - afl->rand_seed[2] = s2; - afl->rand_seed[3] = s3; - -} - -/* This is the long-jump function for the generator. It is equivalent to - 2^192 calls to rand_next(); it can be used to generate 2^64 starting points, - from each of which jump() will generate 2^64 non-overlapping - subsequences for parallel distributed computations. */ - -void long_jump(afl_state_t *afl) { - - static const uint64_t LONG_JUMP[] = {0x76e15d3efefdcbbf, 0xc5004e441c522fb3, - 0x77710069854ee241, 0x39109bb02acbe635}; - - size_t i, b; - uint64_t s0 = 0; - uint64_t s1 = 0; - uint64_t s2 = 0; - uint64_t s3 = 0; - for (i = 0; i < (sizeof(LONG_JUMP) / sizeof(*LONG_JUMP)); i++) - for (b = 0; b < 64; b++) { - - if (LONG_JUMP[i] & UINT64_C(1) << b) { - - s0 ^= afl->rand_seed[0]; - s1 ^= afl->rand_seed[1]; - s2 ^= afl->rand_seed[2]; - s3 ^= afl->rand_seed[3]; - - } - - rand_next(afl); - - } - - afl->rand_seed[0] = s0; - afl->rand_seed[1] = s1; - afl->rand_seed[2] = s2; - afl->rand_seed[3] = s3; - -} - /* we switch from afl's murmur implementation to xxh3 as it is 30% faster - and get 64 bit hashes instead of just 32 bit. Less collisions! :-) */ -- cgit v1.2.3 From ea9db86bb86341e4e2b53c46204e3f86496e6ab9 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 18 Dec 2020 10:20:43 +0100 Subject: mem error fix --- src/afl-forkserver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 3afb94be..90fa55e9 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -641,11 +641,11 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (!fsrv->map_size) { fsrv->map_size = MAP_SIZE; } - if (unlikely(tmp_map_size % 8)) { + if (unlikely(tmp_map_size % 32)) { // should not happen WARNF("Target reported non-aligned map size of %u", tmp_map_size); - tmp_map_size = (((tmp_map_size + 8) >> 3) << 3); + tmp_map_size = (((tmp_map_size + 31) >> 5) << 5); } -- cgit v1.2.3 From 12ebb351dc2b5655b4174539e2b9ee59e4acf893 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Fri, 18 Dec 2020 21:10:39 +0100 Subject: apply nocolor changes --- src/afl-fuzz-state.c | 16 ++++++++++++++++ src/afl-fuzz.c | 15 +++++++++++++++ 2 files changed, 31 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 9c51a3ef..e863c4c7 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -401,6 +401,22 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_crash_exitcode = (u8 *)get_afl_env(afl_environment_variables[i]); +#if defined USE_COLOR && ! defined ALWAYS_COLORED + } else if (!strncmp(env, "AFL_NO_COLOR", + + afl_environment_variable_len)) { + + afl->afl_env.afl_statsd_tags_flavor = + (u8 *)get_afl_env(afl_environment_variables[i]); + + } else if (!strncmp(env, "AFL_NO_COLOUR", + + afl_environment_variable_len)) { + + afl->afl_env.afl_statsd_tags_flavor = + (u8 *)get_afl_env(afl_environment_variables[i]); +#endif + } } else { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 391d4c4f..e0d46f7e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -156,6 +156,12 @@ static void usage(u8 *argv0, int more_help) { if (more_help > 1) { +#if defined USE_COLOR && !defined ALWAYS_COLORED + #define DYN_COLOR "AFL_NO_COLOR or AFL_NO_COLOUR: switch colored console output off\n" +#else + #define DYN_COLOR +#endif + SAYF( "Environment variables used:\n" "LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n" @@ -194,6 +200,9 @@ static void usage(u8 *argv0, int more_help) { "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_UI: switch status screen off\n" + + DYN_COLOR + "AFL_PATH: path to AFL support binaries\n" "AFL_PYTHON_MODULE: mutate and trim inputs with the specified Python module\n" "AFL_QUIET: suppress forkserver status messages\n" @@ -298,6 +307,12 @@ int main(int argc, char **argv_orig, char **envp) { struct timeval tv; struct timezone tz; +#if defined USE_COLOR && defined ALWAYS_COLORED + if (getenv("AFL_NO_COLOR") || getenv("AFL_NO_COLOUR")) { + WARNF("Setting AFL_NO_COLOR has no effect (colors are configured on at compile time)"); + } +#endif + char **argv = argv_cpy_dup(argc, argv_orig); afl_state_t *afl = calloc(1, sizeof(afl_state_t)); -- cgit v1.2.3 From 98ee17bc47b1f1d4664be9955a72727fff8e51fa Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 20 Dec 2020 14:30:06 +0100 Subject: fix endless loop in afl-cc allow/blocklists starting a line with a comment --- src/afl-cc.c | 2 +- src/afl-fuzz-state.c | 3 ++- src/afl-fuzz.c | 14 ++++++++++---- 3 files changed, 13 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 2aeb2178..8593f9b8 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1432,7 +1432,7 @@ int main(int argc, char **argv, char **envp) { " AFL_LLVM_LAF_SPLIT_FLOATS: cascaded comparisons on floats\n" " AFL_LLVM_LAF_TRANSFORM_COMPARES: cascade comparisons for string " "functions\n" - " AFL_LLVM_INSTRUMENT_ALLOW/AFL_LLVM_INSTRUMENT_DENY: enable " + " AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST: enable " "instrument allow/\n" " deny listing (selective instrumentation)\n"); diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index e863c4c7..7053572b 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -401,7 +401,8 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_crash_exitcode = (u8 *)get_afl_env(afl_environment_variables[i]); -#if defined USE_COLOR && ! defined ALWAYS_COLORED +#if defined USE_COLOR && !defined ALWAYS_COLORED + } else if (!strncmp(env, "AFL_NO_COLOR", afl_environment_variable_len)) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e0d46f7e..2af374f2 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -157,7 +157,8 @@ static void usage(u8 *argv0, int more_help) { if (more_help > 1) { #if defined USE_COLOR && !defined ALWAYS_COLORED - #define DYN_COLOR "AFL_NO_COLOR or AFL_NO_COLOUR: switch colored console output off\n" + #define DYN_COLOR \ + "AFL_NO_COLOR or AFL_NO_COLOUR: switch colored console output off\n" #else #define DYN_COLOR #endif @@ -307,11 +308,16 @@ int main(int argc, char **argv_orig, char **envp) { struct timeval tv; struct timezone tz; -#if defined USE_COLOR && defined ALWAYS_COLORED + #if defined USE_COLOR && defined ALWAYS_COLORED if (getenv("AFL_NO_COLOR") || getenv("AFL_NO_COLOUR")) { - WARNF("Setting AFL_NO_COLOR has no effect (colors are configured on at compile time)"); + + WARNF( + "Setting AFL_NO_COLOR has no effect (colors are configured on at " + "compile time)"); + } -#endif + + #endif char **argv = argv_cpy_dup(argc, argv_orig); -- cgit v1.2.3 From 2e3cf10070681375a6c0e63ad39e7ce04ff22684 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 20 Dec 2020 22:53:41 +0100 Subject: document AFL_LLVM_INSTRUMENT option NATIVE --- src/afl-cc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 8593f9b8..6f4801de 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1346,6 +1346,9 @@ int main(int argc, char **argv, char **envp) { "Sub-Modes: (set via env AFL_LLVM_INSTRUMENT, afl-cc selects the best " "available)\n" " PCGUARD: Dominator tree instrumentation (best!) (README.llvm.md)\n" +#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) + " NATIVE: use llvm's native PCGUARD instrumentation (less performant)\n" +#endif " CLASSIC: decision target instrumentation (README.llvm.md)\n" " CTX: CLASSIC + callee context (instrumentation/README.ctx.md)\n" " NGRAM-x: CLASSIC + previous path " -- cgit v1.2.3 From 7e27448dac2191060320831904f32fe9d572bc3d Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 21 Dec 2020 12:19:22 +0100 Subject: another 32 bit fix --- src/afl-cc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 6f4801de..3b8092a9 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1347,7 +1347,8 @@ int main(int argc, char **argv, char **envp) { "available)\n" " PCGUARD: Dominator tree instrumentation (best!) (README.llvm.md)\n" #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) - " NATIVE: use llvm's native PCGUARD instrumentation (less performant)\n" + " NATIVE: use llvm's native PCGUARD instrumentation (less " + "performant)\n" #endif " CLASSIC: decision target instrumentation (README.llvm.md)\n" " CTX: CLASSIC + callee context (instrumentation/README.ctx.md)\n" -- cgit v1.2.3 From 27b9ba45026397ee0605dd88aab359c4c1dea4cc Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 22 Dec 2020 10:51:40 +0100 Subject: better gcc and clang support for afl-cc --- src/afl-cc.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 119 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 3b8092a9..a18f87db 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -62,7 +62,7 @@ u8 use_stdin; /* dummy */ enum { - INSTURMENT_DEFAULT = 0, + INSTRUMENT_DEFAULT = 0, INSTRUMENT_CLASSIC = 1, INSTRUMENT_AFL = 1, INSTRUMENT_PCGUARD = 2, @@ -70,6 +70,8 @@ enum { INSTRUMENT_CFG = 3, INSTRUMENT_LTO = 4, INSTRUMENT_LLVMNATIVE = 5, + INSTRUMENT_GCC = 6, + INSTRUMENT_CLANG = 7, INSTRUMENT_OPT_CTX = 8, INSTRUMENT_OPT_NGRAM = 16 @@ -77,9 +79,24 @@ enum { char instrument_mode_string[18][18] = { - "DEFAULT", "CLASSIC", "PCGUARD", "CFG", "LTO", "", "PCGUARD-NATIVE", - "", "CTX", "", "", "", "", "", - "", "", "NGRAM", "" + "DEFAULT", + "CLASSIC", + "PCGUARD", + "CFG", + "LTO", + "PCGUARD-NATIVE", + "GCC", + "CLANG", + "CTX", + "", + "", + "", + "", + "", + "", + "", + "NGRAM", + "" }; @@ -89,14 +106,15 @@ enum { LTO = 1, LLVM = 2, GCC_PLUGIN = 3, - GCC = 4 + GCC = 4, + CLANG = 5 }; -char compiler_mode_string[6][12] = { +char compiler_mode_string[7][12] = { "AUTOSELECT", "LLVM-LTO", "LLVM", "GCC_PLUGIN", - "GCC", "" + "GCC", "CLANG", "" }; @@ -324,6 +342,10 @@ static void edit_params(u32 argc, char **argv, char **envp) { alt_cxx = clang_mode ? "clang++" : "g++"; + } else if (compiler_mode == CLANG) { + + alt_cxx = "clang++"; + } else { alt_cxx = "g++"; @@ -357,6 +379,10 @@ static void edit_params(u32 argc, char **argv, char **envp) { alt_cc = clang_mode ? "clang" : "gcc"; + } else if (compiler_mode == CLANG) { + + alt_cc = "clang"; + } else { alt_cc = "gcc"; @@ -380,12 +406,16 @@ static void edit_params(u32 argc, char **argv, char **envp) { } - if (compiler_mode == GCC) { + if (compiler_mode == GCC || compiler_mode == CLANG) { cc_params[cc_par_cnt++] = "-B"; cc_params[cc_par_cnt++] = obj_path; - if (clang_mode) { cc_params[cc_par_cnt++] = "-no-integrated-as"; } + if (clang_mode || compiler_mode == CLANG) { + + cc_params[cc_par_cnt++] = "-no-integrated-as"; + + } } @@ -996,12 +1026,14 @@ int main(int argc, char **argv, char **envp) { } else if (strncmp(callname, "afl-gcc", 7) == 0 || - strncmp(callname, "afl-g++", 7) == 0 || - - strncmp(callname, "afl-clang", 9) == 0) { + strncmp(callname, "afl-g++", 7) == 0) { compiler_mode = GCC; + } else if (strncmp(callname, "afl-clang", 9) == 0) { + + compiler_mode = CLANG; + } if ((ptr = getenv("AFL_CC_COMPILER"))) { @@ -1045,6 +1077,7 @@ int main(int argc, char **argv, char **envp) { if (strncmp(callname, "afl-clang", 9) == 0) { clang_mode = 1; + compiler_mode = CLANG; if (strncmp(callname, "afl-clang++", 11) == 0) { plusplus_mode = 1; } @@ -1072,6 +1105,34 @@ int main(int argc, char **argv, char **envp) { compiler_mode = LLVM; + } else if (strncasecmp(ptr, "PCGUARD", 7) == 0 || + + strncasecmp(ptr, "PC-GUARD", 8) == 0) { + + compiler_mode = LLVM; + instrument_mode = INSTRUMENT_PCGUARD; + + } else if (strcasecmp(ptr, "INSTRIM") == 0 || + + strcasecmp(ptr, "CFG") == 0) { + + compiler_mode = LLVM; + instrument_mode = INSTRUMENT_CFG; + + } else if (strcasecmp(ptr, "AFL") == 0 || + + strcasecmp(ptr, "CLASSIC") == 0) { + + compiler_mode = LLVM; + instrument_mode = INSTRUMENT_CLASSIC; + + } else if (strcasecmp(ptr, "LLVMNATIVE") == 0 || + + strcasecmp(ptr, "LLVM-NATIVE") == 0) { + + compiler_mode = LLVM; + instrument_mode = INSTRUMENT_LLVMNATIVE; + } else if (strncasecmp(ptr, "GCC_P", 5) == 0 || strncasecmp(ptr, "GCC-P", 5) == 0 || @@ -1083,6 +1144,10 @@ int main(int argc, char **argv, char **envp) { compiler_mode = GCC; + } else if (strcasecmp(ptr, "CLANG") == 0) { + + compiler_mode = CLANG; + } else FATAL("Unknown --afl-... compiler mode: %s\n", argv[i]); @@ -1212,6 +1277,28 @@ int main(int argc, char **argv, char **envp) { } + if (strcasecmp(ptr, "gcc") == 0) { + + if (!instrument_mode || instrument_mode == INSTRUMENT_GCC) + instrument_mode = INSTRUMENT_GCC; + else if (instrument_mode != INSTRUMENT_GCC) + FATAL("main instrumentation mode already set with %s", + instrument_mode_string[instrument_mode]); + compiler_mode = GCC; + + } + + if (strcasecmp(ptr, "clang") == 0) { + + if (!instrument_mode || instrument_mode == INSTRUMENT_CLANG) + instrument_mode = INSTRUMENT_CLANG; + else if (instrument_mode != INSTRUMENT_CLANG) + FATAL("main instrumentation mode already set with %s", + instrument_mode_string[instrument_mode]); + compiler_mode = CLANG; + + } + if (strncasecmp(ptr, "ctx", strlen("ctx")) == 0) { instrument_opt_mode |= INSTRUMENT_OPT_CTX; @@ -1270,6 +1357,22 @@ int main(int argc, char **argv, char **envp) { } + if (compiler_mode == GCC) { + + if (clang_mode) { + + instrument_mode = CLANG; + + } else { + + instrument_mode = GCC; + + } + + } + + if (compiler_mode == CLANG) { instrument_mode = CLANG; } + if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) { printf("afl-cc" VERSION @@ -1316,7 +1419,7 @@ int main(int argc, char **argv, char **envp) { " [GCC_PLUGIN] gcc plugin: %s%s\n" " CLASSIC DEFAULT no yes yes no no no " " yes\n" - " [GCC] simple gcc: %s%s\n" + " [GCC/CLANG] simple gcc/clang: %s%s\n" " CLASSIC DEFAULT no no no no no no " " no\n\n", have_lto ? "AVAILABLE" : "unavailable!", @@ -1328,7 +1431,7 @@ int main(int argc, char **argv, char **envp) { have_gcc_plugin ? "AVAILABLE" : "unavailable!", compiler_mode == GCC_PLUGIN ? " [SELECTED]" : "", have_gcc ? "AVAILABLE" : "unavailable!", - compiler_mode == GCC ? " [SELECTED]" : ""); + (compiler_mode == GCC || compiler_mode == CLANG) ? " [SELECTED]" : ""); SAYF( "Modes:\n" @@ -1445,7 +1548,8 @@ int main(int argc, char **argv, char **envp) { " AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen " "mutator)\n" " AFL_LLVM_INSTRUMENT: set instrumentation mode:\n" - " CLASSIC, INSTRIM, PCGUARD, LTO, CTX, NGRAM-2 ... NGRAM-16\n" + " CLASSIC, INSTRIM, PCGUARD, LTO, GCC, CLANG, CTX, NGRAM-2 ... " + "NGRAM-16\n" " You can also use the old environment variables instead:\n" " AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n" " AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n" -- cgit v1.2.3 From 9759320266d3f334f71d06eed5267d78de1837d8 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 22 Dec 2020 12:33:58 +0100 Subject: afl-clang-fast fix --- src/afl-cc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index a18f87db..66f4860f 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1030,7 +1030,9 @@ int main(int argc, char **argv, char **envp) { compiler_mode = GCC; - } else if (strncmp(callname, "afl-clang", 9) == 0) { + } else if (strncmp(callname, "afl-clang", 9) == 0 && + + strstr(callname, "fast") == NULL) { compiler_mode = CLANG; @@ -1074,7 +1076,8 @@ int main(int argc, char **argv, char **envp) { } - if (strncmp(callname, "afl-clang", 9) == 0) { + if (strncmp(callname, "afl-clang", 9) == 0 && + strstr(callname, "fast") == NULL) { clang_mode = 1; compiler_mode = CLANG; @@ -1144,7 +1147,7 @@ int main(int argc, char **argv, char **envp) { compiler_mode = GCC; - } else if (strcasecmp(ptr, "CLANG") == 0) { + } else if (strncasecmp(ptr, "CLANG", 5) == 0) { compiler_mode = CLANG; -- cgit v1.2.3 From 2a994e457a75c28272373ba24cd4158239c007fd Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 22 Dec 2020 19:39:49 +0100 Subject: portability: avoid void * arithmetic (UB), avoid GNU extension for array initializations --- src/afl-fuzz-bitmap.c | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 738ba986..a17478f0 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -97,10 +97,10 @@ u32 count_bytes(afl_state_t *afl, u8 *mem) { u32 v = *(ptr++); if (!v) { continue; } - if (v & 0x000000ff) { ++ret; } - if (v & 0x0000ff00) { ++ret; } - if (v & 0x00ff0000) { ++ret; } - if (v & 0xff000000) { ++ret; } + if (v & 0x000000ffU) { ++ret; } + if (v & 0x0000ff00U) { ++ret; } + if (v & 0x00ff0000U) { ++ret; } + if (v & 0xff000000U) { ++ret; } } @@ -124,11 +124,11 @@ u32 count_non_255_bytes(afl_state_t *afl, u8 *mem) { /* This is called on the virgin bitmap, so optimize for the most likely case. */ - if (v == 0xffffffff) { continue; } - if ((v & 0x000000ff) != 0x000000ff) { ++ret; } - if ((v & 0x0000ff00) != 0x0000ff00) { ++ret; } - if ((v & 0x00ff0000) != 0x00ff0000) { ++ret; } - if ((v & 0xff000000) != 0xff000000) { ++ret; } + if (v == 0xffffffffU) { continue; } + if ((v & 0x000000ffU) != 0x000000ffU) { ++ret; } + if ((v & 0x0000ff00U) != 0x0000ff00U) { ++ret; } + if ((v & 0x00ff0000U) != 0x00ff0000U) { ++ret; } + if ((v & 0xff000000U) != 0xff000000U) { ++ret; } } @@ -140,10 +140,15 @@ u32 count_non_255_bytes(afl_state_t *afl, u8 *mem) { and replacing it with 0x80 or 0x01 depending on whether the tuple is hit or not. Called on every new crash or timeout, should be reasonably fast. */ - +#define TIMES4(x) x,x,x,x +#define TIMES8(x) TIMES4(x),TIMES4(x) +#define TIMES16(x) TIMES8(x),TIMES8(x) +#define TIMES32(x) TIMES16(x),TIMES16(x) +#define TIMES64(x) TIMES32(x),TIMES32(x) +#define TIMES255(x) TIMES64(x),TIMES64(x),TIMES64(x),TIMES32(x),TIMES16(x),TIMES8(x),TIMES4(x),x,x,x const u8 simplify_lookup[256] = { - [0] = 1, [1 ... 255] = 128 + [0] = 1, [1] = TIMES255(128) }; @@ -157,13 +162,19 @@ const u8 count_class_lookup8[256] = { [1] = 1, [2] = 2, [3] = 4, - [4 ... 7] = 8, - [8 ... 15] = 16, - [16 ... 31] = 32, - [32 ... 127] = 64, - [128 ... 255] = 128 + [4] = TIMES4(8), + [8] = TIMES8(16), + [16] = TIMES16(32), + [32] = TIMES32(64), + [128] = TIMES64(128) }; +#undef TIMES255 +#undef TIMES64 +#undef TIMES32 +#undef TIMES16 +#undef TIMES8 +#undef TIMES4 u16 count_class_lookup16[65536]; -- cgit v1.2.3 From 8241ded12ecdc4a28d3a99c37ac8cb420f724a86 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 22 Dec 2020 20:19:43 +0100 Subject: more portability non std array initializers --- src/afl-showmap.c | 28 +++++++++++++++++++++------- src/afl-tmin.c | 20 +++++++++++++++----- 2 files changed, 36 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 34a4f30d..b891632a 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -98,11 +98,18 @@ static sharedmem_t * shm_fuzz; /* Classify tuple counts. Instead of mapping to individual bits, as in afl-fuzz.c, we map to more user-friendly numbers between 1 and 8. */ +#define TIMES4(x) x,x,x,x +#define TIMES8(x) TIMES4(x),TIMES4(x) +#define TIMES16(x) TIMES8(x),TIMES8(x) +#define TIMES32(x) TIMES16(x),TIMES16(x) +#define TIMES64(x) TIMES32(x),TIMES32(x) +#define TIMES96(x) TIMES64(x),TIMES32(x) +#define TIMES128(x) TIMES64(x),TIMES64(x) static const u8 count_class_human[256] = { [0] = 0, [1] = 1, [2] = 2, [3] = 3, - [4 ... 7] = 4, [8 ... 15] = 5, [16 ... 31] = 6, [32 ... 127] = 7, - [128 ... 255] = 8 + [4] = TIMES4(4), [8] = TIMES8(5),[16] = TIMES16(6),[32] = TIMES96(7), + [128] = TIMES128(8) }; @@ -112,13 +119,20 @@ static const u8 count_class_binary[256] = { [1] = 1, [2] = 2, [3] = 4, - [4 ... 7] = 8, - [8 ... 15] = 16, - [16 ... 31] = 32, - [32 ... 127] = 64, - [128 ... 255] = 128 + [4] = TIMES4(8), + [8] = TIMES8(16), + [16] = TIMES16(32), + [32] = TIMES32(64), + [128] = TIMES64(128) }; +#undef TIMES128 +#undef TIMES96 +#undef TIMES64 +#undef TIMES32 +#undef TIMES16 +#undef TIMES8 +#undef TIMES4 static void classify_counts(afl_forkserver_t *fsrv) { diff --git a/src/afl-tmin.c b/src/afl-tmin.c index b9045551..6cb0d458 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -98,19 +98,29 @@ static sharedmem_t * shm_fuzz; /* Classify tuple counts. This is a slow & naive version, but good enough here. */ +#define TIMES4(x) x,x,x,x +#define TIMES8(x) TIMES4(x),TIMES4(x) +#define TIMES16(x) TIMES8(x),TIMES8(x) +#define TIMES32(x) TIMES16(x),TIMES16(x) +#define TIMES64(x) TIMES32(x),TIMES32(x) static const u8 count_class_lookup[256] = { [0] = 0, [1] = 1, [2] = 2, [3] = 4, - [4 ... 7] = 8, - [8 ... 15] = 16, - [16 ... 31] = 32, - [32 ... 127] = 64, - [128 ... 255] = 128 + [4] = TIMES4(8), + [8] = TIMES8(16), + [16] = TIMES16(32), + [32] = TIMES32(64), + [128] = TIMES64(128) }; +#undef TIMES64 +#undef TIMES32 +#undef TIMES16 +#undef TIMES8 +#undef TIMES4 static sharedmem_t *deinit_shmem(afl_forkserver_t *fsrv, sharedmem_t * shm_fuzz) { -- cgit v1.2.3 From e790667fd2992ab867382a0946ea7337e01329fa Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 22 Dec 2020 20:29:22 +0100 Subject: one more with nonstd array initializers --- src/afl-analyze.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 2780deff..a6825ef6 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -103,19 +103,29 @@ static u32 map_size = MAP_SIZE; /* Classify tuple counts. This is a slow & naive version, but good enough here. */ +#define TIMES4(x) x,x,x,x +#define TIMES8(x) TIMES4(x),TIMES4(x) +#define TIMES16(x) TIMES8(x),TIMES8(x) +#define TIMES32(x) TIMES16(x),TIMES16(x) +#define TIMES64(x) TIMES32(x),TIMES32(x) static u8 count_class_lookup[256] = { [0] = 0, [1] = 1, [2] = 2, [3] = 4, - [4 ... 7] = 8, - [8 ... 15] = 16, - [16 ... 31] = 32, - [32 ... 127] = 64, - [128 ... 255] = 128 + [4] = TIMES4(8), + [8] = TIMES8(16), + [16] = TIMES16(32), + [32] = TIMES32(64), + [128] = TIMES64(128) }; +#undef TIMES64 +#undef TIMES32 +#undef TIMES16 +#undef TIMES8 +#undef TIMES4 static void classify_counts(u8 *mem) { -- cgit v1.2.3 From 9a5ea5b5c235b236a9c026230133fc2ad014f89d Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 22 Dec 2020 20:33:06 +0100 Subject: workaround for Solaris: NAME_MAX is not defined --- src/afl-fuzz-bitmap.c | 3 +++ src/afl-fuzz-run.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index a17478f0..1cb9b15f 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -25,6 +25,9 @@ #include "afl-fuzz.h" #include +#if !defined NAME_MAX +#define NAME_MAX _XOPEN_NAME_MAX +#endif /* Write bitmap to file. The bitmap is useful mostly for the secret -B option, to focus a separate fuzzing session on a particular diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 60086bd6..32cca579 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -28,6 +28,9 @@ #include #include #include +#if !defined NAME_MAX +#define NAME_MAX _XOPEN_NAME_MAX +#endif #include "cmplog.h" -- cgit v1.2.3 From 03849d147a69cf627746a8ad5f1b653367a56ff5 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 23 Dec 2020 17:56:39 +0100 Subject: warn on _AFL and __AFL env vars --- src/afl-analyze.c | 11 ++++++----- src/afl-common.c | 4 +++- src/afl-fuzz-bitmap.c | 17 ++++++++++------- src/afl-fuzz-run.c | 2 +- src/afl-showmap.c | 25 ++++++++++++++++--------- src/afl-tmin.c | 11 ++++++----- 6 files changed, 42 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/afl-analyze.c b/src/afl-analyze.c index a6825ef6..6dac415b 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -103,11 +103,11 @@ static u32 map_size = MAP_SIZE; /* Classify tuple counts. This is a slow & naive version, but good enough here. */ -#define TIMES4(x) x,x,x,x -#define TIMES8(x) TIMES4(x),TIMES4(x) -#define TIMES16(x) TIMES8(x),TIMES8(x) -#define TIMES32(x) TIMES16(x),TIMES16(x) -#define TIMES64(x) TIMES32(x),TIMES32(x) +#define TIMES4(x) x, x, x, x +#define TIMES8(x) TIMES4(x), TIMES4(x) +#define TIMES16(x) TIMES8(x), TIMES8(x) +#define TIMES32(x) TIMES16(x), TIMES16(x) +#define TIMES64(x) TIMES32(x), TIMES32(x) static u8 count_class_lookup[256] = { [0] = 0, @@ -121,6 +121,7 @@ static u8 count_class_lookup[256] = { [128] = TIMES64(128) }; + #undef TIMES64 #undef TIMES32 #undef TIMES16 diff --git a/src/afl-common.c b/src/afl-common.c index 6dc8abe0..7914f83a 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -432,7 +432,9 @@ void check_environment_vars(char **envp) { char *env, *val; while ((env = envp[index++]) != NULL) { - if (strncmp(env, "ALF_", 4) == 0) { + if (strncmp(env, "ALF_", 4) == 0 || strncmp(env, "_ALF", 4) == 0 || + strncmp(env, "__ALF", 5) == 0 || strncmp(env, "_AFL", 4) == 0 || + strncmp(env, "__AFL", 5) == 0) { WARNF("Potentially mistyped AFL environment variable: %s", env); issue_detected = 1; diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 1cb9b15f..62a8211c 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -26,7 +26,7 @@ #include "afl-fuzz.h" #include #if !defined NAME_MAX -#define NAME_MAX _XOPEN_NAME_MAX + #define NAME_MAX _XOPEN_NAME_MAX #endif /* Write bitmap to file. The bitmap is useful mostly for the secret @@ -143,12 +143,14 @@ u32 count_non_255_bytes(afl_state_t *afl, u8 *mem) { and replacing it with 0x80 or 0x01 depending on whether the tuple is hit or not. Called on every new crash or timeout, should be reasonably fast. */ -#define TIMES4(x) x,x,x,x -#define TIMES8(x) TIMES4(x),TIMES4(x) -#define TIMES16(x) TIMES8(x),TIMES8(x) -#define TIMES32(x) TIMES16(x),TIMES16(x) -#define TIMES64(x) TIMES32(x),TIMES32(x) -#define TIMES255(x) TIMES64(x),TIMES64(x),TIMES64(x),TIMES32(x),TIMES16(x),TIMES8(x),TIMES4(x),x,x,x +#define TIMES4(x) x, x, x, x +#define TIMES8(x) TIMES4(x), TIMES4(x) +#define TIMES16(x) TIMES8(x), TIMES8(x) +#define TIMES32(x) TIMES16(x), TIMES16(x) +#define TIMES64(x) TIMES32(x), TIMES32(x) +#define TIMES255(x) \ + TIMES64(x), TIMES64(x), TIMES64(x), TIMES32(x), TIMES16(x), TIMES8(x), \ + TIMES4(x), x, x, x const u8 simplify_lookup[256] = { [0] = 1, [1] = TIMES255(128) @@ -172,6 +174,7 @@ const u8 count_class_lookup8[256] = { [128] = TIMES64(128) }; + #undef TIMES255 #undef TIMES64 #undef TIMES32 diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 32cca579..d53ba546 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -29,7 +29,7 @@ #include #include #if !defined NAME_MAX -#define NAME_MAX _XOPEN_NAME_MAX + #define NAME_MAX _XOPEN_NAME_MAX #endif #include "cmplog.h" diff --git a/src/afl-showmap.c b/src/afl-showmap.c index b891632a..355b2dc3 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -98,17 +98,23 @@ static sharedmem_t * shm_fuzz; /* Classify tuple counts. Instead of mapping to individual bits, as in afl-fuzz.c, we map to more user-friendly numbers between 1 and 8. */ -#define TIMES4(x) x,x,x,x -#define TIMES8(x) TIMES4(x),TIMES4(x) -#define TIMES16(x) TIMES8(x),TIMES8(x) -#define TIMES32(x) TIMES16(x),TIMES16(x) -#define TIMES64(x) TIMES32(x),TIMES32(x) -#define TIMES96(x) TIMES64(x),TIMES32(x) -#define TIMES128(x) TIMES64(x),TIMES64(x) +#define TIMES4(x) x, x, x, x +#define TIMES8(x) TIMES4(x), TIMES4(x) +#define TIMES16(x) TIMES8(x), TIMES8(x) +#define TIMES32(x) TIMES16(x), TIMES16(x) +#define TIMES64(x) TIMES32(x), TIMES32(x) +#define TIMES96(x) TIMES64(x), TIMES32(x) +#define TIMES128(x) TIMES64(x), TIMES64(x) static const u8 count_class_human[256] = { - [0] = 0, [1] = 1, [2] = 2, [3] = 3, - [4] = TIMES4(4), [8] = TIMES8(5),[16] = TIMES16(6),[32] = TIMES96(7), + [0] = 0, + [1] = 1, + [2] = 2, + [3] = 3, + [4] = TIMES4(4), + [8] = TIMES8(5), + [16] = TIMES16(6), + [32] = TIMES96(7), [128] = TIMES128(8) }; @@ -126,6 +132,7 @@ static const u8 count_class_binary[256] = { [128] = TIMES64(128) }; + #undef TIMES128 #undef TIMES96 #undef TIMES64 diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 6cb0d458..ed928c7c 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -98,11 +98,11 @@ static sharedmem_t * shm_fuzz; /* Classify tuple counts. This is a slow & naive version, but good enough here. */ -#define TIMES4(x) x,x,x,x -#define TIMES8(x) TIMES4(x),TIMES4(x) -#define TIMES16(x) TIMES8(x),TIMES8(x) -#define TIMES32(x) TIMES16(x),TIMES16(x) -#define TIMES64(x) TIMES32(x),TIMES32(x) +#define TIMES4(x) x, x, x, x +#define TIMES8(x) TIMES4(x), TIMES4(x) +#define TIMES16(x) TIMES8(x), TIMES8(x) +#define TIMES32(x) TIMES16(x), TIMES16(x) +#define TIMES64(x) TIMES32(x), TIMES32(x) static const u8 count_class_lookup[256] = { [0] = 0, @@ -116,6 +116,7 @@ static const u8 count_class_lookup[256] = { [128] = TIMES64(128) }; + #undef TIMES64 #undef TIMES32 #undef TIMES16 -- cgit v1.2.3 From a4fd4ea0f46529feb09577a13cc7c053fb22146f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 25 Dec 2020 12:13:45 +0100 Subject: fix LTO --- src/afl-cc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 66f4860f..00e9cfce 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1030,9 +1030,9 @@ int main(int argc, char **argv, char **envp) { compiler_mode = GCC; - } else if (strncmp(callname, "afl-clang", 9) == 0 && + } else if (strcmp(callname, "afl-clang") == 0 || - strstr(callname, "fast") == NULL) { + strcmp(callname, "afl-clang++") == 0) { compiler_mode = CLANG; @@ -1076,13 +1076,13 @@ int main(int argc, char **argv, char **envp) { } - if (strncmp(callname, "afl-clang", 9) == 0 && - strstr(callname, "fast") == NULL) { + if (strcmp(callname, "afl-clang") == 0 || + strcmp(callname, "afl-clang++") == 0) { clang_mode = 1; compiler_mode = CLANG; - if (strncmp(callname, "afl-clang++", 11) == 0) { plusplus_mode = 1; } + if (strcmp(callname, "afl-clang++") == 0) { plusplus_mode = 1; } } -- cgit v1.2.3 From 0b9ca807f2a5e1ef6f43a8cb95356ed21ba3a3e5 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 26 Dec 2020 13:15:05 +0100 Subject: fix exec/s display --- src/afl-common.c | 8 ++++++-- src/afl-fuzz-state.c | 2 +- src/afl-fuzz-stats.c | 35 +++++++++++++++++++++-------------- 3 files changed, 28 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 7914f83a..1928663d 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -630,6 +630,10 @@ u8 *stringify_float(u8 *buf, size_t len, double val) { snprintf(buf, len, "%0.01f", val); + } else if (unlikely(isnan(val) || isinf(val))) { + + strcpy(buf, "inf"); + } else { stringify_int(buf, len, (u64)val); @@ -789,9 +793,9 @@ u8 *u_stringify_float(u8 *buf, double val) { sprintf(buf, "%0.01f", val); - } else if (unlikely(isnan(val) || isfinite(val))) { + } else if (unlikely(isnan(val) || isinf(val))) { - strcpy(buf, "999.9"); + strcpy(buf, "infinite"); } else { diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 7053572b..34456c0d 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -100,7 +100,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->cal_cycles_long = CAL_CYCLES_LONG; afl->hang_tmout = EXEC_TIMEOUT; afl->stats_update_freq = 1; - afl->stats_avg_exec = -1; + afl->stats_avg_exec = 0; afl->skip_deterministic = 1; #ifndef NO_SPLICING afl->use_splicing = 1; diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 50e2ef15..cb0d3dcd 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -369,30 +369,37 @@ void show_stats(afl_state_t *afl) { /* Calculate smoothed exec speed stats. */ - if (!afl->stats_last_execs) { + if (unlikely(!afl->stats_last_execs)) { - if (unlikely(cur_ms == afl->start_time)) --afl->start_time; + if (likely(cur_ms != afl->start_time)) { - afl->stats_avg_exec = - ((double)afl->fsrv.total_execs) * 1000 / (cur_ms - afl->start_time); + afl->stats_avg_exec = + ((double)afl->fsrv.total_execs) * 1000 / (cur_ms - afl->start_time); + + } } else { - double cur_avg = ((double)(afl->fsrv.total_execs - afl->stats_last_execs)) * - 1000 / (cur_ms - afl->stats_last_ms); + if (likely(cur_ms != afl->stats_last_ms)) { - /* If there is a dramatic (5x+) jump in speed, reset the indicator - more quickly. */ + double cur_avg = + ((double)(afl->fsrv.total_execs - afl->stats_last_execs)) * 1000 / + (cur_ms - afl->stats_last_ms); - if (cur_avg * 5 < afl->stats_avg_exec || - cur_avg / 5 > afl->stats_avg_exec) { + /* If there is a dramatic (5x+) jump in speed, reset the indicator + more quickly. */ - afl->stats_avg_exec = cur_avg; + if (cur_avg * 5 < afl->stats_avg_exec || + cur_avg / 5 > afl->stats_avg_exec) { - } + afl->stats_avg_exec = cur_avg; - afl->stats_avg_exec = afl->stats_avg_exec * (1.0 - 1.0 / AVG_SMOOTHING) + - cur_avg * (1.0 / AVG_SMOOTHING); + } + + afl->stats_avg_exec = afl->stats_avg_exec * (1.0 - 1.0 / AVG_SMOOTHING) + + cur_avg * (1.0 / AVG_SMOOTHING); + + } } -- cgit v1.2.3 From 4af0065f4a7518f7df8f8b49c40127e2e674a760 Mon Sep 17 00:00:00 2001 From: David Manouchehri Date: Sat, 26 Dec 2020 14:23:59 -0500 Subject: Fix missing include for macOS. (#660) --- src/afl-ld-lto.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index 16feaa80..19491036 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -45,6 +45,10 @@ #include +#ifdef __APPLE__ +#include +#endif + #define MAX_PARAM_COUNT 4096 static u8 **ld_params; /* Parameters passed to the real 'ld' */ -- cgit v1.2.3 From 8e2b59ffcab0102e3bebe0c4ed64cb9d36de5559 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 26 Dec 2020 23:04:21 +0100 Subject: more flexible system support for afl-frida --- src/afl-ld-lto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index 19491036..fccdb1a5 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -46,7 +46,7 @@ #include #ifdef __APPLE__ -#include + #include #endif #define MAX_PARAM_COUNT 4096 -- cgit v1.2.3 From 688f4ffb89ebf41a497070e8fcf2927510b66874 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 28 Dec 2020 14:01:48 +0100 Subject: added corpus introspection --- src/afl-fuzz-queue.c | 30 ++++++++++++++++++++++++++++++ src/afl-fuzz-run.c | 4 ++++ 2 files changed, 34 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 54afa17c..5dc2d70b 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -190,6 +190,32 @@ void create_alias_table(afl_state_t *afl) { while (nS) afl->alias_probability[S[--nS]] = 1; +#ifdef INTROSPECTION + u8 fn[PATH_MAX]; + snprintf(fn, PATH_MAX, "%s/introspection_corpus.txt", afl->out_dir); + FILE *f = fopen(fn, "a"); + if (f) { + + for (i = 0; i < n; i++) { + + struct queue_entry *q = afl->queue_buf[i]; + fprintf( + f, + "entry=%u name=%s variable=%s disabled=%s len=%u exec_us=%u " + "bitmap_size=%u bitsmap_size=%u tops=%u weight=%f perf_score=%f\n", + i, q->fname, q->var_behavior ? "true" : "false", + q->disabled ? "true" : "false", q->len, (u32)q->exec_us, + q->bitmap_size, q->bitsmap_size, q->tc_ref, q->weight, q->perf_score); + + } + + fprintf(f, "\n"); + fclose(f); + + } + +#endif + /* fprintf(stderr, " entry alias probability perf_score filename\n"); for (u32 i = 0; i < n; ++i) @@ -398,6 +424,10 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { q->trace_mini = NULL; q->testcase_buf = NULL; +#ifdef INTROSPECTION + q->bitsmap_size = afl->bitsmap_size; +#endif + if (q->depth > afl->max_depth) { afl->max_depth = q->depth; } if (afl->queue_top) { diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index d53ba546..339fb9c3 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -380,6 +380,10 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, } +#ifdef INTROSPECTION + if (unlikely(!q->bitsmap_size)) q->bitsmap_size = afl->bitsmap_size; +#endif + classify_counts(&afl->fsrv); cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); if (q->exec_cksum != cksum) { -- cgit v1.2.3 From d103e39f5866fa29a13e7e8d4204b1e962100369 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 28 Dec 2020 17:06:55 +0100 Subject: fix instrumentation type display --- src/afl-cc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 00e9cfce..758b958b 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1364,17 +1364,17 @@ int main(int argc, char **argv, char **envp) { if (clang_mode) { - instrument_mode = CLANG; + instrument_mode = INSTRUMENT_CLANG; } else { - instrument_mode = GCC; + instrument_mode = INSTRUMENT_GCC; } } - if (compiler_mode == CLANG) { instrument_mode = CLANG; } + if (compiler_mode == CLANG) { instrument_mode = INSTRUMENT_CLANG; } if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) { -- cgit v1.2.3 From 0922763db1df494c1547db296934a1d66286319f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20B=C3=B6hme?= Date: Tue, 29 Dec 2020 14:57:05 +1100 Subject: Update afl-fuzz-queue.c --- src/afl-fuzz-queue.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 5dc2d70b..d4b35ad2 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -112,12 +112,8 @@ void create_alias_table(afl_state_t *afl) { struct queue_entry *q = afl->queue_buf[i]; - if (!q->disabled) { - - q->weight = compute_weight(afl, q, avg_exec_us, avg_bitmap_size); - q->perf_score = calculate_score(afl, q); - - } + q->weight = q->disabled ? 0 : compute_weight(afl, q, avg_exec_us, avg_bitmap_size); + q->perf_score = q->disabled ? 0 : calculate_score(afl, q); sum += q->weight; -- cgit v1.2.3 From 83c1378fc1810d177d9cdfa2c00f62bbadd98f00 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 29 Dec 2020 14:19:35 +0100 Subject: fix afl-clang on 32-Bit systems --- src/afl-cc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 758b958b..e6a6718e 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -879,7 +879,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { #ifndef __ANDROID__ - if (compiler_mode != GCC) { + if (compiler_mode != GCC && compiler_mode != CLANG) { switch (bit_mode) { -- cgit v1.2.3 From 80767480f0f40d380c83069b5f82b808c76493cc Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 29 Dec 2020 18:13:36 +0100 Subject: Revert "fix afl-clang on 32-Bit systems" This reverts commit 83c1378fc1810d177d9cdfa2c00f62bbadd98f00. --- src/afl-cc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index e6a6718e..758b958b 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -879,7 +879,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { #ifndef __ANDROID__ - if (compiler_mode != GCC && compiler_mode != CLANG) { + if (compiler_mode != GCC) { switch (bit_mode) { -- cgit v1.2.3 From 107c79b84b7cd7d90e8f9e10b3a46fbafcae39eb Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 29 Dec 2020 18:17:50 +0100 Subject: now fix afl-clang compiles on 32-Bit properly --- src/afl-cc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 758b958b..e6a6718e 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -879,7 +879,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { #ifndef __ANDROID__ - if (compiler_mode != GCC) { + if (compiler_mode != GCC && compiler_mode != CLANG) { switch (bit_mode) { -- cgit v1.2.3 From e9a306a50eee1444ae40b961fbc8d942541348ca Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 29 Dec 2020 10:25:48 +0100 Subject: fix localtime warnings from CodeQL --- src/afl-fuzz-init.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index ec937f29..75c0384f 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1668,19 +1668,20 @@ static void handle_existing_out_dir(afl_state_t *afl) { if (afl->in_place_resume && rmdir(fn)) { time_t cur_t = time(0); - struct tm *t = localtime(&cur_t); + struct tm t; + localtime_r(&cur_t, &t); #ifndef SIMPLE_FILES u8 *nfn = alloc_printf("%s.%04d-%02d-%02d-%02d:%02d:%02d", fn, - t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, - t->tm_hour, t->tm_min, t->tm_sec); + t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, + t.tm_hour, t.tm_min, t.tm_sec); #else - u8 *nfn = alloc_printf("%s_%04d%02d%02d%02d%02d%02d", fn, t->tm_year + 1900, - t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, - t->tm_sec); + u8 *nfn = alloc_printf("%s_%04d%02d%02d%02d%02d%02d", fn, t.tm_year + 1900, + t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, + t.tm_sec); #endif /* ^!SIMPLE_FILES */ @@ -1699,19 +1700,20 @@ static void handle_existing_out_dir(afl_state_t *afl) { if (afl->in_place_resume && rmdir(fn)) { time_t cur_t = time(0); - struct tm *t = localtime(&cur_t); + struct tm t; + localtime_r(&cur_t, &t); #ifndef SIMPLE_FILES u8 *nfn = alloc_printf("%s.%04d-%02d-%02d-%02d:%02d:%02d", fn, - t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, - t->tm_hour, t->tm_min, t->tm_sec); + t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, + t.tm_hour, t.tm_min, t.tm_sec); #else - u8 *nfn = alloc_printf("%s_%04d%02d%02d%02d%02d%02d", fn, t->tm_year + 1900, - t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, - t->tm_sec); + u8 *nfn = alloc_printf("%s_%04d%02d%02d%02d%02d%02d", fn, t.tm_year + 1900, + t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, + t.tm_sec); #endif /* ^!SIMPLE_FILES */ -- cgit v1.2.3 From d687fbdfb4d3fc1485c9ab9d46da2546ae243f4a Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 29 Dec 2020 19:53:56 +0100 Subject: fix CodeQL warning on theoretically possible unsigned overflow --- src/afl-fuzz-redqueen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 9a9ac33f..5b3ade1d 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -456,7 +456,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - if (SHAPE_BYTES(h->shape) >= 1 && *status != 1) { + if (/* SHAPE_BYTES(h->shape) >= 1 && */ *status != 1) { /* avoid CodeQL warning on unsigned overflow */ if (its_len >= 1 && *buf_8 == (u8)pattern && *o_buf_8 == (u8)o_pattern) { -- cgit v1.2.3 From 0246fe9200ec29afd56a545c41b9888be84eafbf Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 30 Dec 2020 10:34:22 +0100 Subject: fix 32-bit mode, fix weighting --- src/afl-fuzz-init.c | 32 ++++++++++++++++---------------- src/afl-fuzz-queue.c | 31 ++++++++++++++++++++++--------- src/afl-fuzz-redqueen.c | 3 ++- src/afl-performance.c | 8 ++++---- 4 files changed, 44 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 75c0384f..dbffa4f9 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1667,21 +1667,21 @@ static void handle_existing_out_dir(afl_state_t *afl) { if (afl->in_place_resume && rmdir(fn)) { - time_t cur_t = time(0); - struct tm t; + time_t cur_t = time(0); + struct tm t; localtime_r(&cur_t, &t); #ifndef SIMPLE_FILES - u8 *nfn = alloc_printf("%s.%04d-%02d-%02d-%02d:%02d:%02d", fn, - t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, - t.tm_hour, t.tm_min, t.tm_sec); + u8 *nfn = + alloc_printf("%s.%04d-%02d-%02d-%02d:%02d:%02d", fn, t.tm_year + 1900, + t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); #else - u8 *nfn = alloc_printf("%s_%04d%02d%02d%02d%02d%02d", fn, t.tm_year + 1900, - t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, - t.tm_sec); + u8 *nfn = + alloc_printf("%s_%04d%02d%02d%02d%02d%02d", fn, t.tm_year + 1900, + t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); #endif /* ^!SIMPLE_FILES */ @@ -1699,21 +1699,21 @@ static void handle_existing_out_dir(afl_state_t *afl) { if (afl->in_place_resume && rmdir(fn)) { - time_t cur_t = time(0); - struct tm t; + time_t cur_t = time(0); + struct tm t; localtime_r(&cur_t, &t); #ifndef SIMPLE_FILES - u8 *nfn = alloc_printf("%s.%04d-%02d-%02d-%02d:%02d:%02d", fn, - t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, - t.tm_hour, t.tm_min, t.tm_sec); + u8 *nfn = + alloc_printf("%s.%04d-%02d-%02d-%02d:%02d:%02d", fn, t.tm_year + 1900, + t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); #else - u8 *nfn = alloc_printf("%s_%04d%02d%02d%02d%02d%02d", fn, t.tm_year + 1900, - t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, - t.tm_sec); + u8 *nfn = + alloc_printf("%s_%04d%02d%02d%02d%02d%02d", fn, t.tm_year + 1900, + t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); #endif /* ^!SIMPLE_FILES */ diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index d4b35ad2..928cdb62 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -97,30 +97,43 @@ void create_alias_table(afl_state_t *afl) { double avg_exec_us = 0.0; double avg_bitmap_size = 0.0; + u32 active = 0; + for (i = 0; i < n; i++) { struct queue_entry *q = afl->queue_buf[i]; - avg_exec_us += q->exec_us; - avg_bitmap_size += log(q->bitmap_size); + + // disabled entries might have timings and bitmap values + if (likely(!q->disabled)) { + + avg_exec_us += q->exec_us; + avg_bitmap_size += log(q->bitmap_size); + ++active; + + } } - avg_exec_us /= afl->queued_paths; - avg_bitmap_size /= afl->queued_paths; + avg_exec_us /= active; + avg_bitmap_size /= active; for (i = 0; i < n; i++) { struct queue_entry *q = afl->queue_buf[i]; - q->weight = q->disabled ? 0 : compute_weight(afl, q, avg_exec_us, avg_bitmap_size); - q->perf_score = q->disabled ? 0 : calculate_score(afl, q); + if (likely(!q->disabled)) { + + q->weight = compute_weight(afl, q, avg_exec_us, avg_bitmap_size); + q->perf_score = calculate_score(afl, q); + sum += q->weight; - sum += q->weight; + } } for (i = 0; i < n; i++) { + // weight is always 0 for disabled entries P[i] = (afl->queue_buf[i]->weight * n) / sum; } @@ -139,8 +152,8 @@ void create_alias_table(afl_state_t *afl) { for (i = 0; i < n; i++) { - struct queue_entry *q = afl->queue_buf[i]; - P[i] = (q->perf_score * n) / sum; + // perf_score is always 0 for disabled entries + P[i] = (afl->queue_buf[i]->perf_score * n) / sum; } diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 5b3ade1d..37d66aef 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -456,7 +456,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - if (/* SHAPE_BYTES(h->shape) >= 1 && */ *status != 1) { /* avoid CodeQL warning on unsigned overflow */ + /* avoid CodeQL warning on unsigned overflow */ + if (/* SHAPE_BYTES(h->shape) >= 1 && */ *status != 1) { if (its_len >= 1 && *buf_8 == (u8)pattern && *o_buf_8 == (u8)o_pattern) { diff --git a/src/afl-performance.c b/src/afl-performance.c index 89b170eb..4bca95d6 100644 --- a/src/afl-performance.c +++ b/src/afl-performance.c @@ -56,13 +56,13 @@ inline AFL_RAND_RETURN rand_next(afl_state_t *afl) { // RomuTrio32 inline AFL_RAND_RETURN rand_next(afl_state_t *afl) { - AFL_RAND_RETURN xp = afl->rand_seed[0], yp = afl->rand_seed[1], - zp = afl->rand_seed[2]; + AFL_RAND_RETURN xp = (u32)afl->rand_seed[0], yp = (u32)afl->rand_seed[1], + zp = (u32)afl->rand_seed[2]; afl->rand_seed[0] = 3323815723u * zp; afl->rand_seed[1] = yp - xp; - afl->rand_seed[1] = ROTL(afl->rand_seed[1], 6); + afl->rand_seed[1] = ROTL((u32)afl->rand_seed[1], 6); afl->rand_seed[2] = zp - yp; - afl->rand_seed[2] = ROTL(afl->rand_seed[2], 22); + afl->rand_seed[2] = ROTL((u32)afl->rand_seed[2], 22); return xp; } -- cgit v1.2.3 From f38595f6b47c538ba4e8a177e81c596040ee99c9 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 30 Dec 2020 12:32:55 +0100 Subject: better weighting --- src/afl-fuzz-queue.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 928cdb62..9a0d199e 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -45,25 +45,19 @@ inline u32 select_next_queue_entry(afl_state_t *afl) { double compute_weight(afl_state_t *afl, struct queue_entry *q, double avg_exec_us, double avg_bitmap_size) { - u32 hits; + double weight = 1.0; if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) { - hits = afl->n_fuzz[q->n_fuzz_entry]; - if (hits == 0) { hits = 1; } - - } else { - - hits = 1; + u32 hits = afl->n_fuzz[q->n_fuzz_entry]; + if (likely(hits)) { weight *= log10(hits) + 1; } } - double weight = 1.0; weight *= avg_exec_us / q->exec_us; - weight *= log(q->bitmap_size) / avg_bitmap_size; - weight /= log10(hits) + 1; + weight *= (log(q->bitmap_size) / avg_bitmap_size); - if (q->favored) weight *= 5; + if (unlikely(q->favored)) weight *= 5; return weight; @@ -210,11 +204,13 @@ void create_alias_table(afl_state_t *afl) { struct queue_entry *q = afl->queue_buf[i]; fprintf( f, - "entry=%u name=%s variable=%s disabled=%s len=%u exec_us=%u " + "entry=%u name=%s favored=%s variable=%s disabled=%s len=%u " + "exec_us=%u " "bitmap_size=%u bitsmap_size=%u tops=%u weight=%f perf_score=%f\n", - i, q->fname, q->var_behavior ? "true" : "false", - q->disabled ? "true" : "false", q->len, (u32)q->exec_us, - q->bitmap_size, q->bitsmap_size, q->tc_ref, q->weight, q->perf_score); + i, q->fname, q->favored ? "true" : "false", + q->var_behavior ? "true" : "false", q->disabled ? "true" : "false", + q->len, (u32)q->exec_us, q->bitmap_size, q->bitsmap_size, q->tc_ref, + q->weight, q->perf_score); } @@ -226,10 +222,10 @@ void create_alias_table(afl_state_t *afl) { #endif /* - fprintf(stderr, " entry alias probability perf_score filename\n"); - for (u32 i = 0; i < n; ++i) - fprintf(stderr, " %5u %5u %11u %0.9f %s\n", i, afl->alias_table[i], - afl->alias_probability[i], afl->queue_buf[i]->perf_score, + fprintf(stderr, " entry alias probability perf_score weight + filename\n"); for (u32 i = 0; i < n; ++i) fprintf(stderr, " %5u %5u %11u + %0.9f %0.9f %s\n", i, afl->alias_table[i], afl->alias_probability[i], + afl->queue_buf[i]->perf_score, afl->queue_buf[i]->weight, afl->queue_buf[i]->fname); */ -- cgit v1.2.3 From b0d69f1b6995a9ddc0aebb0c289da79ebd3fc5e9 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 30 Dec 2020 13:02:11 +0100 Subject: cleanup of hot fix for -s on 32-bit --- src/afl-performance.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-performance.c b/src/afl-performance.c index 4bca95d6..89b170eb 100644 --- a/src/afl-performance.c +++ b/src/afl-performance.c @@ -56,13 +56,13 @@ inline AFL_RAND_RETURN rand_next(afl_state_t *afl) { // RomuTrio32 inline AFL_RAND_RETURN rand_next(afl_state_t *afl) { - AFL_RAND_RETURN xp = (u32)afl->rand_seed[0], yp = (u32)afl->rand_seed[1], - zp = (u32)afl->rand_seed[2]; + AFL_RAND_RETURN xp = afl->rand_seed[0], yp = afl->rand_seed[1], + zp = afl->rand_seed[2]; afl->rand_seed[0] = 3323815723u * zp; afl->rand_seed[1] = yp - xp; - afl->rand_seed[1] = ROTL((u32)afl->rand_seed[1], 6); + afl->rand_seed[1] = ROTL(afl->rand_seed[1], 6); afl->rand_seed[2] = zp - yp; - afl->rand_seed[2] = ROTL((u32)afl->rand_seed[2], 22); + afl->rand_seed[2] = ROTL(afl->rand_seed[2], 22); return xp; } -- cgit v1.2.3 From 7e6645d5a25b874b978430eeb7d1ddce1f681d98 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 31 Dec 2020 11:51:10 +0100 Subject: float2double --- src/afl-fuzz-stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index cb0d3dcd..1c211da6 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -120,8 +120,8 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, cur_time - afl->last_avg_exec_update >= 60000))) { afl->last_avg_execs_saved = - (float)(1000 * (afl->fsrv.total_execs - afl->last_avg_execs)) / - (float)(cur_time - afl->last_avg_exec_update); + (double)(1000 * (afl->fsrv.total_execs - afl->last_avg_execs)) / + (double)(cur_time - afl->last_avg_exec_update); afl->last_avg_execs = afl->fsrv.total_execs; afl->last_avg_exec_update = cur_time; -- cgit v1.2.3 From fac373ec9e4a0a35a5f0491a34e790137ca17dee Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 1 Jan 2021 13:42:58 +0100 Subject: try new weighting --- src/afl-fuzz-queue.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 9a0d199e..de750f36 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -43,7 +43,8 @@ inline u32 select_next_queue_entry(afl_state_t *afl) { } double compute_weight(afl_state_t *afl, struct queue_entry *q, - double avg_exec_us, double avg_bitmap_size) { + double avg_exec_us, double avg_bitmap_size, + double avg_top_size) { double weight = 1.0; @@ -54,9 +55,9 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q, } - weight *= avg_exec_us / q->exec_us; - weight *= (log(q->bitmap_size) / avg_bitmap_size); - + if (likely(afl->schedule < RARE)) { weight *= (avg_exec_us / q->exec_us); } + weight *= (q->bitmap_size / avg_bitmap_size); + weight *= (log(q->tc_ref) / avg_top_size); if (unlikely(q->favored)) weight *= 5; return weight; @@ -91,6 +92,7 @@ void create_alias_table(afl_state_t *afl) { double avg_exec_us = 0.0; double avg_bitmap_size = 0.0; + double avg_top_size = 0.0; u32 active = 0; for (i = 0; i < n; i++) { @@ -101,7 +103,8 @@ void create_alias_table(afl_state_t *afl) { if (likely(!q->disabled)) { avg_exec_us += q->exec_us; - avg_bitmap_size += log(q->bitmap_size); + avg_bitmap_size += q->bitmap_size; + avg_top_size += log(q->tc_ref); ++active; } @@ -110,6 +113,7 @@ void create_alias_table(afl_state_t *afl) { avg_exec_us /= active; avg_bitmap_size /= active; + avg_top_size /= active; for (i = 0; i < n; i++) { @@ -117,7 +121,8 @@ void create_alias_table(afl_state_t *afl) { if (likely(!q->disabled)) { - q->weight = compute_weight(afl, q, avg_exec_us, avg_bitmap_size); + q->weight = + compute_weight(afl, q, avg_exec_us, avg_bitmap_size, avg_top_size); q->perf_score = calculate_score(afl, q); sum += q->weight; -- cgit v1.2.3 From 33abd70647789fc0e3960e76351bec5793944918 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 2 Jan 2021 20:06:02 +0100 Subject: typo --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 2af374f2..897c2f1e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1534,7 +1534,7 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->pending_not_fuzzed) { - FATAL("We need at least on valid input seed that does not crash!"); + FATAL("We need at least one valid input seed that does not crash!"); } -- cgit v1.2.3 From 1857df8d06c48b7d0bf99eee5dea2de595cdf4c5 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 3 Jan 2021 00:37:56 +0100 Subject: cleanup --- src/afl-fuzz-redqueen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 37d66aef..df215e9c 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -802,13 +802,13 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, u64 exec_cksum) { u8 r = 1; - if (afl->orig_cmp_map == NULL) { + if (unlikely(!afl->orig_cmp_map)) { afl->orig_cmp_map = ck_alloc_nozero(sizeof(struct cmp_map)); } - if (afl->pass_stats == NULL) { + if (unlikely(!afl->pass_stats)) { afl->pass_stats = ck_alloc(sizeof(struct afl_pass_stat) * CMP_MAP_W); -- cgit v1.2.3 From 880513651d271db538eeb3f04d046cf9ce6021f8 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 3 Jan 2021 10:13:55 +0100 Subject: cmplog cleanup --- src/afl-fuzz-redqueen.c | 40 +++------------------------------------- 1 file changed, 3 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index df215e9c..bbd47ab2 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -99,12 +99,12 @@ static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u64 *cksum) { } -static void rand_replace(afl_state_t *afl, u8 *buf, u32 len) { +static void xor_replace(u8 *buf, u32 len) { u32 i; for (i = 0; i < len; ++i) { - buf[i] = rand_below(afl, 256); + buf[i] ^= 0xff; } @@ -115,8 +115,6 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) { struct range *ranges = add_range(NULL, 0, len); u8 * backup = ck_alloc_nozero(len); - u8 needs_write = 0; - u64 orig_hit_cnt, new_hit_cnt; orig_hit_cnt = afl->queued_paths + afl->unique_crashes; @@ -136,7 +134,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) { /* Range not empty */ memcpy(backup, buf + rng->start, s); - rand_replace(afl, buf + rng->start, s); + xor_replace(buf + rng->start, s); u64 cksum; u64 start_us = get_cur_time_us(); @@ -158,10 +156,6 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) { ranges = add_range(ranges, rng->start + s / 2 + 1, rng->end); memcpy(buf + rng->start, backup, s); - } else { - - needs_write = 1; - } } @@ -191,32 +185,6 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) { } - // save the input with the high entropy - - if (needs_write) { - - s32 fd; - - if (afl->no_unlink) { - - fd = open(afl->queue_cur->fname, O_WRONLY | O_CREAT | O_TRUNC, 0600); - - } else { - - unlink(afl->queue_cur->fname); /* ignore errors */ - fd = open(afl->queue_cur->fname, O_WRONLY | O_CREAT | O_EXCL, 0600); - - } - - if (fd < 0) { PFATAL("Unable to create '%s'", afl->queue_cur->fname); } - - ck_write(fd, buf, len, afl->queue_cur->fname); - afl->queue_cur->len = len; // no-op, just to be 100% safe - - close(fd); - - } - return 0; checksum_fail: @@ -232,8 +200,6 @@ checksum_fail: } - // TODO: clang notices a _potential_ leak of mem pointed to by rng - return 1; } -- cgit v1.2.3 From 58039d181afcc22b54f42abeabe67ae9bb43e251 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 3 Jan 2021 12:34:23 +0100 Subject: stability fix --- src/afl-fuzz-redqueen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index bbd47ab2..c5db8fa1 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -854,7 +854,7 @@ exit_its: afl->stage_finds[STAGE_ITS] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_ITS] += afl->fsrv.total_execs - orig_execs; - memcpy(orig_buf, buf, len); + memcpy(buf, orig_buf, len); return r; -- cgit v1.2.3 From c6e038fe25789caa8da777f53154de1bd7b4e178 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Mon, 4 Jan 2021 20:40:53 +0100 Subject: code cleanups (shadowed vars, (un)signed type mismatches, format types, etc.) --- src/afl-analyze.c | 4 +-- src/afl-cc.c | 74 ++++++++++++++++++++++++++++--------------------- src/afl-common.c | 20 ++++++------- src/afl-forkserver.c | 4 +-- src/afl-fuzz-bitmap.c | 2 +- src/afl-fuzz-extras.c | 6 ++-- src/afl-fuzz-mutators.c | 28 ++++++++++++------- src/afl-fuzz-one.c | 24 ++++++++-------- src/afl-fuzz-queue.c | 5 ++-- src/afl-fuzz-redqueen.c | 9 ++++-- src/afl-fuzz-run.c | 2 +- src/afl-fuzz-stats.c | 8 +++--- src/afl-fuzz.c | 8 +++--- src/afl-ld-lto.c | 6 ++-- src/afl-showmap.c | 12 ++++---- src/afl-tmin.c | 4 +-- 16 files changed, 119 insertions(+), 97 deletions(-) (limited to 'src') diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 6dac415b..8fc4434a 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -903,8 +903,8 @@ static void usage(u8 *argv0) { "Execution control settings:\n" " -f file - input file read by the tested program (stdin)\n" - " -t msec - timeout for each run (%d ms)\n" - " -m megs - memory limit for child process (%d MB)\n" + " -t msec - timeout for each run (%u ms)\n" + " -m megs - memory limit for child process (%u MB)\n" " -Q - use binary-only instrumentation (QEMU mode)\n" " -U - use unicorn-based instrumentation (Unicorn mode)\n" " -W - use qemu-based instrumentation with Wine (Wine " diff --git a/src/afl-cc.c b/src/afl-cc.c index e6a6718e..180ab3c4 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -120,8 +120,10 @@ char compiler_mode_string[7][12] = { u8 *getthecwd() { - static u8 fail[] = ""; - if (getcwd(cwd, sizeof(cwd)) == NULL) return fail; + if (getcwd(cwd, sizeof(cwd)) == NULL) { + static u8 fail[] = ""; + return fail; + } return cwd; } @@ -654,9 +656,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { } - u32 idx; if (lto_mode && argc > 1) { + u32 idx; for (idx = 1; idx < argc; idx++) { if (!strncasecmp(argv[idx], "-fpic", 5)) have_pic = 1; @@ -1208,12 +1210,12 @@ int main(int argc, char **argv, char **envp) { if (getenv("AFL_LLVM_INSTRUMENT")) { - u8 *ptr = strtok(getenv("AFL_LLVM_INSTRUMENT"), ":,;"); + u8 *ptr2 = strtok(getenv("AFL_LLVM_INSTRUMENT"), ":,;"); - while (ptr) { + while (ptr2) { - if (strncasecmp(ptr, "afl", strlen("afl")) == 0 || - strncasecmp(ptr, "classic", strlen("classic")) == 0) { + if (strncasecmp(ptr2, "afl", strlen("afl")) == 0 || + strncasecmp(ptr2, "classic", strlen("classic")) == 0) { if (instrument_mode == INSTRUMENT_LTO) { @@ -1229,8 +1231,8 @@ int main(int argc, char **argv, char **envp) { } - if (strncasecmp(ptr, "pc-guard", strlen("pc-guard")) == 0 || - strncasecmp(ptr, "pcguard", strlen("pcguard")) == 0) { + if (strncasecmp(ptr2, "pc-guard", strlen("pc-guard")) == 0 || + strncasecmp(ptr2, "pcguard", strlen("pcguard")) == 0) { if (!instrument_mode || instrument_mode == INSTRUMENT_PCGUARD) instrument_mode = INSTRUMENT_PCGUARD; @@ -1241,8 +1243,8 @@ int main(int argc, char **argv, char **envp) { } // this is a hidden option - if (strncasecmp(ptr, "llvmnative", strlen("llvmnative")) == 0 || - strncasecmp(ptr, "llvm-native", strlen("llvm-native")) == 0) { + if (strncasecmp(ptr2, "llvmnative", strlen("llvmnative")) == 0 || + strncasecmp(ptr2, "llvm-native", strlen("llvm-native")) == 0) { if (!instrument_mode || instrument_mode == INSTRUMENT_LLVMNATIVE) instrument_mode = INSTRUMENT_LLVMNATIVE; @@ -1252,8 +1254,8 @@ int main(int argc, char **argv, char **envp) { } - if (strncasecmp(ptr, "cfg", strlen("cfg")) == 0 || - strncasecmp(ptr, "instrim", strlen("instrim")) == 0) { + if (strncasecmp(ptr2, "cfg", strlen("cfg")) == 0 || + strncasecmp(ptr2, "instrim", strlen("instrim")) == 0) { if (instrument_mode == INSTRUMENT_LTO) { @@ -1269,7 +1271,7 @@ int main(int argc, char **argv, char **envp) { } - if (strncasecmp(ptr, "lto", strlen("lto")) == 0) { + if (strncasecmp(ptr2, "lto", strlen("lto")) == 0) { lto_mode = 1; if (!instrument_mode || instrument_mode == INSTRUMENT_LTO) @@ -1280,7 +1282,7 @@ int main(int argc, char **argv, char **envp) { } - if (strcasecmp(ptr, "gcc") == 0) { + if (strcasecmp(ptr2, "gcc") == 0) { if (!instrument_mode || instrument_mode == INSTRUMENT_GCC) instrument_mode = INSTRUMENT_GCC; @@ -1291,7 +1293,7 @@ int main(int argc, char **argv, char **envp) { } - if (strcasecmp(ptr, "clang") == 0) { + if (strcasecmp(ptr2, "clang") == 0) { if (!instrument_mode || instrument_mode == INSTRUMENT_CLANG) instrument_mode = INSTRUMENT_CLANG; @@ -1302,29 +1304,29 @@ int main(int argc, char **argv, char **envp) { } - if (strncasecmp(ptr, "ctx", strlen("ctx")) == 0) { + if (strncasecmp(ptr2, "ctx", strlen("ctx")) == 0) { instrument_opt_mode |= INSTRUMENT_OPT_CTX; setenv("AFL_LLVM_CTX", "1", 1); } - if (strncasecmp(ptr, "ngram", strlen("ngram")) == 0) { + if (strncasecmp(ptr2, "ngram", strlen("ngram")) == 0) { - ptr += strlen("ngram"); - while (*ptr && (*ptr < '0' || *ptr > '9')) - ptr++; + ptr2 += strlen("ngram"); + while (*ptr2 && (*ptr2 < '0' || *ptr2 > '9')) + ptr2++; - if (!*ptr) { + if (!*ptr2) { - if ((ptr = getenv("AFL_LLVM_NGRAM_SIZE")) == NULL) + if ((ptr2 = getenv("AFL_LLVM_NGRAM_SIZE")) == NULL) FATAL( "you must set the NGRAM size with (e.g. for value 2) " "AFL_LLVM_INSTRUMENT=ngram-2"); } - ngram_size = atoi(ptr); + ngram_size = atoi(ptr2); if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX) FATAL( "NGRAM instrumentation option must be between 2 and " @@ -1332,12 +1334,12 @@ int main(int argc, char **argv, char **envp) { "(%u)", NGRAM_SIZE_MAX); instrument_opt_mode |= (INSTRUMENT_OPT_NGRAM); - ptr = alloc_printf("%u", ngram_size); - setenv("AFL_LLVM_NGRAM_SIZE", ptr, 1); + ptr2 = alloc_printf("%u", ngram_size); + setenv("AFL_LLVM_NGRAM_SIZE", ptr2, 1); } - ptr = strtok(NULL, ":,;"); + ptr2 = strtok(NULL, ":,;"); } @@ -1448,20 +1450,28 @@ int main(int argc, char **argv, char **envp) { " The best is LTO but it often needs RANLIB and AR settings outside " "of afl-cc.\n\n"); +#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) +#define NATIVE_MSG \ + " NATIVE: use llvm's native PCGUARD instrumentation (less " \ + "performant)\n" +#else +#define NATIVE_MSG "" +#endif + SAYF( "Sub-Modes: (set via env AFL_LLVM_INSTRUMENT, afl-cc selects the best " "available)\n" " PCGUARD: Dominator tree instrumentation (best!) (README.llvm.md)\n" -#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) - " NATIVE: use llvm's native PCGUARD instrumentation (less " - "performant)\n" -#endif + + NATIVE_MSG + " CLASSIC: decision target instrumentation (README.llvm.md)\n" " CTX: CLASSIC + callee context (instrumentation/README.ctx.md)\n" " NGRAM-x: CLASSIC + previous path " "((instrumentation/README.ngram.md)\n" " INSTRIM: Dominator tree (for LLVM <= 6.0) " "(instrumentation/README.instrim.md)\n\n"); +#undef NATIVE_MSG SAYF( "Features: (see documentation links)\n" @@ -1625,7 +1635,7 @@ int main(int argc, char **argv, char **envp) { if (!instrument_mode) { instrument_mode = INSTRUMENT_CFG; - ptr = instrument_mode_string[instrument_mode]; + //ptr = instrument_mode_string[instrument_mode]; } diff --git a/src/afl-common.c b/src/afl-common.c index 1928663d..21cb6ab4 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -696,16 +696,16 @@ u8 *stringify_mem_size(u8 *buf, size_t len, u64 val) { u8 *stringify_time_diff(u8 *buf, size_t len, u64 cur_ms, u64 event_ms) { - u64 delta; - s32 t_d, t_h, t_m, t_s; - u8 val_buf[STRINGIFY_VAL_SIZE_MAX]; - if (!event_ms) { snprintf(buf, len, "none seen yet"); } else { + u64 delta; + s32 t_d, t_h, t_m, t_s; + u8 val_buf[STRINGIFY_VAL_SIZE_MAX]; + delta = cur_ms - event_ms; t_d = delta / 1000 / 60 / 60 / 24; @@ -858,16 +858,16 @@ u8 *u_stringify_mem_size(u8 *buf, u64 val) { u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) { - u64 delta; - s32 t_d, t_h, t_m, t_s; - u8 val_buf[STRINGIFY_VAL_SIZE_MAX]; - if (!event_ms) { sprintf(buf, "none seen yet"); } else { + u64 delta; + s32 t_d, t_h, t_m, t_s; + u8 val_buf[STRINGIFY_VAL_SIZE_MAX]; + delta = cur_ms - event_ms; t_d = delta / 1000 / 60 / 60 / 24; @@ -895,8 +895,8 @@ u32 get_map_size(void) { map_size = atoi(ptr); if (map_size < 8 || map_size > (1 << 29)) { - FATAL("illegal AFL_MAP_SIZE %u, must be between %u and %u", map_size, 8, - 1 << 29); + FATAL("illegal AFL_MAP_SIZE %u, must be between %u and %u", map_size, 8U, + 1U << 29); } diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 90fa55e9..d6195cb5 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -213,7 +213,7 @@ restart_select: static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) { unsigned char tmp[4] = {0, 0, 0, 0}; - pid_t child_pid = -1; + pid_t child_pid; if (!be_quiet) { ACTF("Using Fauxserver:"); } @@ -1104,7 +1104,7 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, "Unable to communicate with fork server. Some possible reasons:\n\n" " - You've run out of memory. Use -m to increase the the memory " "limit\n" - " to something higher than %lld.\n" + " to something higher than %llu.\n" " - The binary or one of the libraries it uses manages to " "create\n" " threads before the forkserver initializes.\n" diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 62a8211c..85a01f98 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -703,7 +703,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (!classified) { classify_counts(&afl->fsrv); - classified = 1; +// classified = 1; } diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 171cce96..04f0878c 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -266,7 +266,7 @@ static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len, if (afl->extras_cnt > afl->max_det_extras) { - WARNF("More than %d tokens - will use them probabilistically.", + WARNF("More than %u tokens - will use them probabilistically.", afl->max_det_extras); } @@ -431,7 +431,6 @@ void dedup_extras(afl_state_t *afl) { /* Adds a new extra / dict entry. */ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { - u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX]; u32 i, found = 0; for (i = 0; i < afl->extras_cnt; i++) { @@ -451,6 +450,7 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { if (len > MAX_DICT_FILE) { + u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX]; WARNF("Extra '%.*s' is too big (%s, limit is %s), skipping file!", (int)len, mem, stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len), stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE)); @@ -481,7 +481,7 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { if (afl->extras_cnt == afl->max_det_extras + 1) { - WARNF("More than %d tokens - will use them probabilistically.", + WARNF("More than %u tokens - will use them probabilistically.", afl->max_det_extras); } diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 0c85458e..5da692d3 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -316,16 +316,20 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, /* Initialize trimming in the custom mutator */ afl->stage_cur = 0; - afl->stage_max = mutator->afl_custom_init_trim(mutator->data, in_buf, q->len); - if (unlikely(afl->stage_max) < 0) { + s32 retval = mutator->afl_custom_init_trim(mutator->data, in_buf, q->len); + if (unlikely(retval) < 0) { - FATAL("custom_init_trim error ret: %d", afl->stage_max); + FATAL("custom_init_trim error ret: %d", retval); + } else { + + afl->stage_max = retval; + } if (afl->not_on_tty && afl->debug) { - SAYF("[Custom Trimming] START: Max %d iterations, %u bytes", afl->stage_max, + SAYF("[Custom Trimming] START: Max %u iterations, %u bytes", afl->stage_max, q->len); } @@ -343,7 +347,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, if (unlikely(!retbuf)) { - FATAL("custom_trim failed (ret %zd)", retlen); + FATAL("custom_trim failed (ret %zu)", retlen); } else if (unlikely(retlen > orig_len)) { @@ -409,7 +413,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, if (afl->not_on_tty && afl->debug) { - SAYF("[Custom Trimming] SUCCESS: %d/%d iterations (now at %u bytes)", + SAYF("[Custom Trimming] SUCCESS: %u/%u iterations (now at %u bytes)", afl->stage_cur, afl->stage_max, q->len); } @@ -417,16 +421,20 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, } else { /* Tell the custom mutator that the trimming was unsuccessful */ - afl->stage_cur = mutator->afl_custom_post_trim(mutator->data, 0); - if (unlikely(afl->stage_cur < 0)) { + s32 retval2 = mutator->afl_custom_post_trim(mutator->data, 0); + if (unlikely(retval2 < 0)) { + + FATAL("Error ret in custom_post_trim: %d", retval2); + + } else { - FATAL("Error ret in custom_post_trim: %d", afl->stage_cur); + afl->stage_cur = retval2; } if (afl->not_on_tty && afl->debug) { - SAYF("[Custom Trimming] FAILURE: %d/%d iterations", afl->stage_cur, + SAYF("[Custom Trimming] FAILURE: %u/%u iterations", afl->stage_cur, afl->stage_max); } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index e6fa6064..f9509e86 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -368,7 +368,7 @@ static void locate_diffs(u8 *ptr1, u8 *ptr2, u32 len, s32 *first, s32 *last) { u8 fuzz_one_original(afl_state_t *afl) { - s32 len, temp_len; + u32 len, temp_len; u32 j; u32 i; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; @@ -545,7 +545,7 @@ u8 fuzz_one_original(afl_state_t *afl) { else orig_perf = perf_score = calculate_score(afl, afl->queue_cur); - if (unlikely(perf_score <= 0)) { goto abandon_entry; } + if (unlikely(perf_score == 0)) { goto abandon_entry; } if (unlikely(afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized)) { @@ -902,7 +902,7 @@ u8 fuzz_one_original(afl_state_t *afl) { orig_hit_cnt = new_hit_cnt; - for (i = 0; (s32)i < len - 1; ++i) { + for (i = 0; i < len - 1; ++i) { /* Let's consult the effector map... */ @@ -945,7 +945,7 @@ u8 fuzz_one_original(afl_state_t *afl) { orig_hit_cnt = new_hit_cnt; - for (i = 0; (s32)i < len - 3; ++i) { + for (i = 0; i < len - 3; ++i) { /* Let's consult the effector map... */ if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] && @@ -1405,7 +1405,7 @@ skip_arith: orig_hit_cnt = new_hit_cnt; - for (i = 0; (s32)i < len - 1; ++i) { + for (i = 0; i < len - 1; ++i) { u16 orig = *(u16 *)(out_buf + i); @@ -1493,7 +1493,7 @@ skip_arith: orig_hit_cnt = new_hit_cnt; - for (i = 0; (s32)i < len - 3; i++) { + for (i = 0; i < len - 3; i++) { u32 orig = *(u32 *)(out_buf + i); @@ -1850,7 +1850,7 @@ custom_mutator_stage: if (unlikely(!mutated_buf)) { - FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size); + FATAL("Error in custom_fuzz. Size returned: %zu", mutated_size); } @@ -2026,7 +2026,7 @@ havoc_stage: el->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE); if (unlikely(!custom_havoc_buf)) { - FATAL("Error in custom_havoc (return %zd)", new_len); + FATAL("Error in custom_havoc (return %zu)", new_len); } @@ -2458,7 +2458,7 @@ havoc_stage: u32 use_extra = rand_below(afl, afl->a_extras_cnt); u32 extra_len = afl->a_extras[use_extra].len; - if ((s32)extra_len > temp_len) { break; } + if (extra_len > temp_len) { break; } u32 insert_at = rand_below(afl, temp_len - extra_len + 1); #ifdef INTROSPECTION @@ -2476,7 +2476,7 @@ havoc_stage: u32 use_extra = rand_below(afl, afl->extras_cnt); u32 extra_len = afl->extras[use_extra].len; - if ((s32)extra_len > temp_len) { break; } + if (extra_len > temp_len) { break; } u32 insert_at = rand_below(afl, temp_len - extra_len + 1); #ifdef INTROSPECTION @@ -2577,7 +2577,7 @@ havoc_stage: u32 copy_from, copy_to, copy_len; copy_len = choose_block_len(afl, new_len - 1); - if ((s32)copy_len > temp_len) copy_len = temp_len; + if (copy_len > temp_len) copy_len = temp_len; copy_from = rand_below(afl, new_len - copy_len + 1); copy_to = rand_below(afl, temp_len - copy_len + 1); @@ -2952,7 +2952,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { else orig_perf = perf_score = calculate_score(afl, afl->queue_cur); - if (unlikely(perf_score <= 0)) { goto abandon_entry; } + if (unlikely(perf_score == 0)) { goto abandon_entry; } if (unlikely(afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized)) { diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 9a0d199e..cd41bafc 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -489,11 +489,12 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { void destroy_queue(afl_state_t *afl) { - struct queue_entry *q; u32 i; for (i = 0; i < afl->queued_paths; i++) { + struct queue_entry *q; + q = afl->queue_buf[i]; ck_free(q->fname); ck_free(q->trace_mini); @@ -996,7 +997,7 @@ inline void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q, if (unlikely(!q->testcase_buf)) { - PFATAL("Unable to malloc '%s' with len %d", q->fname, len); + PFATAL("Unable to malloc '%s' with len %u", q->fname, len); } diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index c5db8fa1..7dba1caa 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -445,6 +445,9 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { u32 k; u8 cons_ff = 0, cons_0 = 0; + + if (shape > sizeof(v)) FATAL("shape is greater than %zu, please report!", sizeof(v)); + for (k = 0; k < shape; ++k) { if (b[k] == 0) { @@ -453,7 +456,7 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { } else if (b[k] == 0xff) { - ++cons_0; + ++cons_ff; } else { @@ -667,12 +670,12 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { u8 status = 0; // opt not in the paper - u32 fails = 0; +// u32 fails = 0; u8 found_one = 0; for (i = 0; i < loggeds; ++i) { - fails = 0; + u32 fails = 0; struct cmpfn_operands *o = &((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[i]; diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 339fb9c3..11d8204b 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -682,7 +682,7 @@ void sync_fuzzers(afl_state_t *afl) { // same time. If so, the first temporary main node running again will demote // themselves so this is not an issue - u8 path[PATH_MAX]; +// u8 path2[PATH_MAX]; afl->is_main_node = 1; sprintf(path, "%s/is_main_node", afl->out_dir); int fd = open(path, O_CREAT | O_RDWR, 0644); diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 1c211da6..c8366174 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -31,7 +31,6 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { - char *val; u8 fn[PATH_MAX]; snprintf(fn, PATH_MAX, "%s/fuzzer_setup", afl->out_dir); FILE *f = create_ffile(fn); @@ -44,6 +43,7 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { for (i = 0; i < s_afl_env; ++i) { + char *val; if ((val = getenv(afl_environment_variables[i])) != NULL) { fprintf(f, "%s=%s\n", afl_environment_variables[i], val); @@ -228,7 +228,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, if (afl->virgin_bits[i] != 0xff) { - fprintf(f, " %d[%02x]", i, afl->virgin_bits[i]); + fprintf(f, " %u[%02x]", i, afl->virgin_bits[i]); } @@ -238,7 +238,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, fprintf(f, "var_bytes :"); for (i = 0; i < afl->fsrv.map_size; i++) { - if (afl->var_bytes[i]) { fprintf(f, " %d", i); } + if (afl->var_bytes[i]) { fprintf(f, " %u", i); } } @@ -1163,7 +1163,7 @@ void show_init_stats(afl_state_t *afl) { } else { - ACTF("-t option specified. We'll use an exec timeout of %d ms.", + ACTF("-t option specified. We'll use an exec timeout of %u ms.", afl->fsrv.exec_tmout); } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 897c2f1e..e239b47f 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -99,8 +99,8 @@ static void usage(u8 *argv0, int more_help) { " lin, quad> -- see docs/power_schedules.md\n" " -f file - location read by the fuzzed program (default: stdin " "or @@)\n" - " -t msec - timeout for each run (auto-scaled, 50-%d ms)\n" - " -m megs - memory limit for child process (%d MB, 0 = no limit)\n" + " -t msec - timeout for each run (auto-scaled, 50-%u ms)\n" + " -m megs - memory limit for child process (%u MB, 0 = no limit)\n" " -Q - use binary-only instrumentation (QEMU mode)\n" " -U - use unicorn-based instrumentation (Unicorn mode)\n" " -W - use qemu-based instrumentation with Wine (Wine " @@ -299,7 +299,7 @@ int main(int argc, char **argv_orig, char **envp) { s32 opt, i, auto_sync = 0 /*, user_set_cache = 0*/; u64 prev_queued = 0; - u32 sync_interval_cnt = 0, seek_to = 0, show_help = 0, map_size = MAP_SIZE; + u32 sync_interval_cnt = 0, seek_to = 0, show_help = 0, map_size = get_map_size(); u8 *extras_dir[4]; u8 mem_limit_given = 0, exit_1 = 0, debug = 0, extras_dir_cnt = 0 /*, have_p = 0*/; @@ -326,7 +326,7 @@ int main(int argc, char **argv_orig, char **envp) { if (get_afl_env("AFL_DEBUG")) { debug = afl->debug = 1; } - map_size = get_map_size(); +// map_size = get_map_size(); afl_state_init(afl, map_size); afl->debug = debug; afl_fsrv_init(&afl->fsrv); diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index fccdb1a5..1d54fda0 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -187,7 +187,7 @@ static void edit_params(int argc, char **argv) { if (debug) DEBUGF( - "passthrough=%s instrim=%d, gold_pos=%d, gold_present=%s " + "passthrough=%s instrim=%u, gold_pos=%u, gold_present=%s " "inst_present=%s rt_present=%s rt_lto_present=%s\n", passthrough ? "true" : "false", instrim, gold_pos, gold_present ? "true" : "false", inst_present ? "true" : "false", @@ -253,10 +253,10 @@ static void edit_params(int argc, char **argv) { int main(int argc, char **argv) { s32 pid, i, status; - u8 * ptr; +// u8 * ptr; char thecwd[PATH_MAX]; - if ((ptr = getenv("AFL_LD_CALLER")) != NULL) { + if (getenv("AFL_LD_CALLER") != NULL) { FATAL("ld loop detected! Set AFL_REAL_LD!\n"); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 355b2dc3..c0223a07 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -662,7 +662,7 @@ static void usage(u8 *argv0) { "Execution control settings:\n" " -t msec - timeout for each run (none)\n" - " -m megs - memory limit for child process (%d MB)\n" + " -m megs - memory limit for child process (%u MB)\n" " -Q - use binary-only instrumentation (QEMU mode)\n" " -U - use Unicorn-based instrumentation (Unicorn mode)\n" " -W - use qemu-based instrumentation with Wine (Wine mode)\n" @@ -1014,7 +1014,7 @@ int main(int argc, char **argv_orig, char **envp) { DIR * dir_in, *dir_out = NULL; struct dirent *dir_ent; - int done = 0; +// int done = 0; u8 infile[PATH_MAX], outfile[PATH_MAX]; u8 wait_for_gdb = 0; #if !defined(DT_REG) @@ -1090,11 +1090,11 @@ int main(int argc, char **argv_orig, char **envp) { if (get_afl_env("AFL_DEBUG")) { - int i = optind; + int j = optind; DEBUGF("%s:", fsrv->target_path); - while (argv[i] != NULL) { + while (argv[j] != NULL) { - SAYF(" \"%s\"", argv[i++]); + SAYF(" \"%s\"", argv[j++]); } @@ -1143,7 +1143,7 @@ int main(int argc, char **argv_orig, char **envp) { if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz); - while (done == 0 && (dir_ent = readdir(dir_in))) { + while ((dir_ent = readdir(dir_in))) { if (dir_ent->d_name[0] == '.') { diff --git a/src/afl-tmin.c b/src/afl-tmin.c index ed928c7c..09d97f58 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -835,8 +835,8 @@ static void usage(u8 *argv0) { "Execution control settings:\n" " -f file - input file read by the tested program (stdin)\n" - " -t msec - timeout for each run (%d ms)\n" - " -m megs - memory limit for child process (%d MB)\n" + " -t msec - timeout for each run (%u ms)\n" + " -m megs - memory limit for child process (%u MB)\n" " -Q - use binary-only instrumentation (QEMU mode)\n" " -U - use unicorn-based instrumentation (Unicorn mode)\n" " -W - use qemu-based instrumentation with Wine (Wine " -- cgit v1.2.3 From 6c095b3937565e0e3c645cab706269e8c764701e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 4 Jan 2021 23:13:56 +0100 Subject: code format --- src/afl-cc.c | 15 +++++++++------ src/afl-fuzz-bitmap.c | 2 +- src/afl-fuzz-extras.c | 2 +- src/afl-fuzz-mutators.c | 2 +- src/afl-fuzz-queue.c | 2 +- src/afl-fuzz-redqueen.c | 7 ++++--- src/afl-fuzz-run.c | 2 +- src/afl-fuzz-stats.c | 2 +- src/afl-fuzz.c | 5 +++-- src/afl-ld-lto.c | 4 ++-- src/afl-showmap.c | 6 +++--- 11 files changed, 27 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 180ab3c4..db2dcd14 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -121,9 +121,12 @@ char compiler_mode_string[7][12] = { u8 *getthecwd() { if (getcwd(cwd, sizeof(cwd)) == NULL) { + static u8 fail[] = ""; return fail; + } + return cwd; } @@ -1451,11 +1454,11 @@ int main(int argc, char **argv, char **envp) { "of afl-cc.\n\n"); #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) -#define NATIVE_MSG \ - " NATIVE: use llvm's native PCGUARD instrumentation (less " \ - "performant)\n" + #define NATIVE_MSG \ + " NATIVE: use llvm's native PCGUARD instrumentation (less " \ + "performant)\n" #else -#define NATIVE_MSG "" + #define NATIVE_MSG "" #endif SAYF( @@ -1463,7 +1466,7 @@ int main(int argc, char **argv, char **envp) { "available)\n" " PCGUARD: Dominator tree instrumentation (best!) (README.llvm.md)\n" - NATIVE_MSG + NATIVE_MSG " CLASSIC: decision target instrumentation (README.llvm.md)\n" " CTX: CLASSIC + callee context (instrumentation/README.ctx.md)\n" @@ -1635,7 +1638,7 @@ int main(int argc, char **argv, char **envp) { if (!instrument_mode) { instrument_mode = INSTRUMENT_CFG; - //ptr = instrument_mode_string[instrument_mode]; + // ptr = instrument_mode_string[instrument_mode]; } diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 85a01f98..ed8c2510 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -703,7 +703,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (!classified) { classify_counts(&afl->fsrv); -// classified = 1; + // classified = 1; } diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 04f0878c..a3583651 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -450,7 +450,7 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { if (len > MAX_DICT_FILE) { - u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX]; + u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX]; WARNF("Extra '%.*s' is too big (%s, limit is %s), skipping file!", (int)len, mem, stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len), stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE)); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 5da692d3..089707b9 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -324,7 +324,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, } else { afl->stage_max = retval; - + } if (afl->not_on_tty && afl->debug) { diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index cd41bafc..7b8c039b 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -489,7 +489,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { void destroy_queue(afl_state_t *afl) { - u32 i; + u32 i; for (i = 0; i < afl->queued_paths; i++) { diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 7dba1caa..28585afe 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -446,7 +446,8 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { u32 k; u8 cons_ff = 0, cons_0 = 0; - if (shape > sizeof(v)) FATAL("shape is greater than %zu, please report!", sizeof(v)); + if (shape > sizeof(v)) + FATAL("shape is greater than %zu, please report!", sizeof(v)); for (k = 0; k < shape; ++k) { @@ -670,8 +671,8 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { u8 status = 0; // opt not in the paper -// u32 fails = 0; - u8 found_one = 0; + // u32 fails = 0; + u8 found_one = 0; for (i = 0; i < loggeds; ++i) { diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 11d8204b..41557707 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -682,7 +682,7 @@ void sync_fuzzers(afl_state_t *afl) { // same time. If so, the first temporary main node running again will demote // themselves so this is not an issue -// u8 path2[PATH_MAX]; + // u8 path2[PATH_MAX]; afl->is_main_node = 1; sprintf(path, "%s/is_main_node", afl->out_dir); int fd = open(path, O_CREAT | O_RDWR, 0644); diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index c8366174..e86f2aeb 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -31,7 +31,7 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { - u8 fn[PATH_MAX]; + u8 fn[PATH_MAX]; snprintf(fn, PATH_MAX, "%s/fuzzer_setup", afl->out_dir); FILE *f = create_ffile(fn); u32 i; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e239b47f..063134fb 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -299,7 +299,8 @@ int main(int argc, char **argv_orig, char **envp) { s32 opt, i, auto_sync = 0 /*, user_set_cache = 0*/; u64 prev_queued = 0; - u32 sync_interval_cnt = 0, seek_to = 0, show_help = 0, map_size = get_map_size(); + u32 sync_interval_cnt = 0, seek_to = 0, show_help = 0, + map_size = get_map_size(); u8 *extras_dir[4]; u8 mem_limit_given = 0, exit_1 = 0, debug = 0, extras_dir_cnt = 0 /*, have_p = 0*/; @@ -326,7 +327,7 @@ int main(int argc, char **argv_orig, char **envp) { if (get_afl_env("AFL_DEBUG")) { debug = afl->debug = 1; } -// map_size = get_map_size(); + // map_size = get_map_size(); afl_state_init(afl, map_size); afl->debug = debug; afl_fsrv_init(&afl->fsrv); diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index 1d54fda0..7a4d9132 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -252,8 +252,8 @@ static void edit_params(int argc, char **argv) { int main(int argc, char **argv) { - s32 pid, i, status; -// u8 * ptr; + s32 pid, i, status; + // u8 * ptr; char thecwd[PATH_MAX]; if (getenv("AFL_LD_CALLER") != NULL) { diff --git a/src/afl-showmap.c b/src/afl-showmap.c index c0223a07..d50601fc 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1014,9 +1014,9 @@ int main(int argc, char **argv_orig, char **envp) { DIR * dir_in, *dir_out = NULL; struct dirent *dir_ent; -// int done = 0; - u8 infile[PATH_MAX], outfile[PATH_MAX]; - u8 wait_for_gdb = 0; + // int done = 0; + u8 infile[PATH_MAX], outfile[PATH_MAX]; + u8 wait_for_gdb = 0; #if !defined(DT_REG) struct stat statbuf; #endif -- cgit v1.2.3 From 6b54310452a1b743a90ad45fcc511f59dd7821ec Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 5 Jan 2021 12:30:26 +0100 Subject: selective instrumentation documented --- src/afl-cc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index db2dcd14..964df57f 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -827,6 +827,20 @@ static void edit_params(u32 argc, char **argv, char **envp) { "extern unsigned char *__afl_fuzz_ptr;" "unsigned char __afl_fuzz_alt[1048576];" "unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt;"; + cc_params[cc_par_cnt++] = + "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;" + "void __afl_coverage_discard();" + "void __afl_coverage_abort();" + "void __afl_coverage_on();" + "void __afl_coverage_off();"; + cc_params[cc_par_cnt++] = + "-D__AFL_COVERAGE_START_OFF()=int __afl_selective_coverage_start_off = " + "1;"; + cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_ON()=__afl_coverage_on()"; + cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_OFF()=__afl_coverage_off()"; + cc_params[cc_par_cnt++] = + "-D__AFL_COVERAGE_DISCARD()=__afl_coverage_discard()"; + cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_ABORT()=__afl_coverage_abort()"; cc_params[cc_par_cnt++] = "-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : " "__afl_fuzz_alt_ptr)"; -- cgit v1.2.3 From faefad564be4b6bd8b311cb4990e8fd33acb5c1c Mon Sep 17 00:00:00 2001 From: hexcoder Date: Tue, 5 Jan 2021 16:49:04 +0000 Subject: Haiku afl-system-config disable debugger, afl-cc.c avoid -lrt --- src/afl-cc.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 964df57f..27bf8cf0 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -792,8 +792,10 @@ static void edit_params(u32 argc, char **argv, char **envp) { } -#if defined(USEMMAP) && !defined(__HAIKU__) +#if defined(USEMMAP) +#if !defined(__HAIKU__) cc_params[cc_par_cnt++] = "-lrt"; +#endif #endif cc_params[cc_par_cnt++] = "-D__AFL_HAVE_MANUAL_CONTROL=1"; @@ -950,9 +952,11 @@ static void edit_params(u32 argc, char **argv, char **envp) { alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); #endif - #ifdef USEMMAP + #if defined(USEMMAP) + #if !defined(__HAIKU__) cc_params[cc_par_cnt++] = "-lrt"; #endif + #endif } @@ -1622,12 +1626,17 @@ int main(int argc, char **argv, char **envp) { if (have_lto) SAYF("afl-cc LTO with ld=%s %s\n", AFL_REAL_LD, AFL_CLANG_FLTO); if (have_llvm) - SAYF("afl-cc LLVM version %d with the the binary path \"%s\".\n", + SAYF("afl-cc LLVM version %d using binary path \"%s\".\n", LLVM_MAJOR, LLVM_BINDIR); #endif -#ifdef USEMMAP +#if defined(USEMMAP) +#if !defined(__HAIKU__) + cc_params[cc_par_cnt++] = "-lrt"; SAYF("Compiled with shm_open support (adds -lrt when linking).\n"); +#else + SAYF("Compiled with shm_open support.\n"); +#endif #else SAYF("Compiled with shmat support.\n"); #endif -- cgit v1.2.3 From 4c78bb70802a85ffad6aee0f234f26901cd563f9 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 5 Jan 2021 22:13:55 +0100 Subject: cpp fix --- src/afl-cc.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 27bf8cf0..e61dc6d2 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -829,12 +829,25 @@ static void edit_params(u32 argc, char **argv, char **envp) { "extern unsigned char *__afl_fuzz_ptr;" "unsigned char __afl_fuzz_alt[1048576];" "unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt;"; - cc_params[cc_par_cnt++] = - "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;" - "void __afl_coverage_discard();" - "void __afl_coverage_abort();" - "void __afl_coverage_on();" - "void __afl_coverage_off();"; + if (plusplus_mode) { + + "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;" + "extern \"C\" void __afl_coverage_discard();" + "extern \"C\" void __afl_coverage_abort();" + "extern \"C\" void __afl_coverage_on();" + "extern \"C\" void __afl_coverage_off();"; + + } else { + + cc_params[cc_par_cnt++] = + "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;" + "void __afl_coverage_discard();" + "void __afl_coverage_abort();" + "void __afl_coverage_on();" + "void __afl_coverage_off();"; + + } + cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_START_OFF()=int __afl_selective_coverage_start_off = " "1;"; -- cgit v1.2.3 From 52c221fc484317d2cd3926ae31ac891bad8cc93a Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 6 Jan 2021 09:35:47 +0100 Subject: selective coverage fix --- src/afl-cc.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index e61dc6d2..999ee7f1 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -793,9 +793,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { } #if defined(USEMMAP) -#if !defined(__HAIKU__) + #if !defined(__HAIKU__) cc_params[cc_par_cnt++] = "-lrt"; -#endif + #endif #endif cc_params[cc_par_cnt++] = "-D__AFL_HAVE_MANUAL_CONTROL=1"; @@ -829,13 +829,15 @@ static void edit_params(u32 argc, char **argv, char **envp) { "extern unsigned char *__afl_fuzz_ptr;" "unsigned char __afl_fuzz_alt[1048576];" "unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt;"; + if (plusplus_mode) { - "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;" - "extern \"C\" void __afl_coverage_discard();" - "extern \"C\" void __afl_coverage_abort();" - "extern \"C\" void __afl_coverage_on();" - "extern \"C\" void __afl_coverage_off();"; + cc_params[cc_par_cnt++] = + "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;" + "extern \"C\" void __afl_coverage_discard();" + "extern \"C\" void __afl_coverage_abort();" + "extern \"C\" void __afl_coverage_on();" + "extern \"C\" void __afl_coverage_off();"; } else { @@ -966,9 +968,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { #endif #if defined(USEMMAP) - #if !defined(__HAIKU__) + #if !defined(__HAIKU__) cc_params[cc_par_cnt++] = "-lrt"; - #endif + #endif #endif } @@ -1639,17 +1641,17 @@ int main(int argc, char **argv, char **envp) { if (have_lto) SAYF("afl-cc LTO with ld=%s %s\n", AFL_REAL_LD, AFL_CLANG_FLTO); if (have_llvm) - SAYF("afl-cc LLVM version %d using binary path \"%s\".\n", - LLVM_MAJOR, LLVM_BINDIR); + SAYF("afl-cc LLVM version %d using binary path \"%s\".\n", LLVM_MAJOR, + LLVM_BINDIR); #endif #if defined(USEMMAP) -#if !defined(__HAIKU__) + #if !defined(__HAIKU__) cc_params[cc_par_cnt++] = "-lrt"; SAYF("Compiled with shm_open support (adds -lrt when linking).\n"); -#else + #else SAYF("Compiled with shm_open support.\n"); -#endif + #endif #else SAYF("Compiled with shmat support.\n"); #endif -- cgit v1.2.3 From 9cdf5c415015e4e80b577c021b8b9fcf8a3d58fb Mon Sep 17 00:00:00 2001 From: buherator Date: Thu, 7 Jan 2021 22:35:34 +0100 Subject: User defined kill signal value (#678) * Adding AFL_KILL_SIGNAL environment variable Controlling the kill signal used to end forked processes. * Checking validity of AFL_KILL_SIGNAL env variable This commit also sets a valid value in the environment to avoid duplicating code in at_exit(). Changing data type of fsrv->kill_signal to u8 to match last_kill_signal. * Adding afl_kill_signal to AFL (environment) state This commit simply introduces a struct member for future use. The env variable is not used from the afl struct but from fsrv, where its validity is checked, resulting in a FATAL in case of errors. --- src/afl-forkserver.c | 44 +++++++++++++++++++++++++++++++++++++++----- src/afl-fuzz-state.c | 11 +++++++++-- src/afl-fuzz.c | 13 +++++++++++-- 3 files changed, 59 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index d6195cb5..70fb9572 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -95,6 +95,29 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) { fsrv->uses_asan = false; fsrv->init_child_func = fsrv_exec_child; + fsrv->kill_signal = SIGKILL; + + char *kill_signal_env = get_afl_env("AFL_KILL_SIGNAL"); + if (kill_signal_env) { + + char *endptr; + u8 signal_code; + signal_code = (u8)strtoul(kill_signal_env, &endptr, 10); + /* Did we manage to parse the full string? */ + if (*endptr != '\0' || endptr == kill_signal_env) { + + FATAL("Invalid kill signal value!"); + + } + + fsrv->kill_signal = signal_code; + + } else { + + /* Using hardcoded code for SIGKILL for the sake of simplicity */ + setenv("AFL_KILL_SIGNAL", "9", 1); + + } list_append(&fsrv_list, fsrv); @@ -126,6 +149,8 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->init_child_func = from->init_child_func; // Note: do not copy ->add_extra_func + fsrv_to->kill_signal = from->kill_signal; + list_append(&fsrv_list, fsrv_to); } @@ -559,12 +584,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (!time_ms) { - kill(fsrv->fsrv_pid, SIGKILL); + kill(fsrv->fsrv_pid, fsrv->kill_signal); } else if (time_ms > fsrv->init_tmout) { fsrv->last_run_timed_out = 1; - kill(fsrv->fsrv_pid, SIGKILL); + kill(fsrv->fsrv_pid, fsrv->kill_signal); } else { @@ -944,10 +969,10 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, static void afl_fsrv_kill(afl_forkserver_t *fsrv) { - if (fsrv->child_pid > 0) { kill(fsrv->child_pid, SIGKILL); } + if (fsrv->child_pid > 0) { kill(fsrv->child_pid, fsrv->kill_signal); } if (fsrv->fsrv_pid > 0) { - kill(fsrv->fsrv_pid, SIGKILL); + kill(fsrv->fsrv_pid, fsrv->kill_signal); if (waitpid(fsrv->fsrv_pid, NULL, 0) <= 0) { WARNF("error waitpid\n"); } } @@ -1091,7 +1116,7 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, /* If there was no response from forkserver after timeout seconds, we kill the child. The forkserver should inform us afterwards */ - kill(fsrv->child_pid, SIGKILL); + kill(fsrv->child_pid, fsrv->kill_signal); fsrv->last_run_timed_out = 1; if (read(fsrv->fsrv_st_fd, &fsrv->child_status, 4) < 4) { exec_ms = 0; } @@ -1137,6 +1162,15 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, /* Report outcome to caller. */ + /* TODO We use SIGTERM here as an indicator of Xen mode, + although it's not equivalent! */ + if (fsrv->kill_signal == SIGTERM && !*stop_soon_p && + fsrv->last_run_timed_out) { + + return FSRV_RUN_TMOUT; + + } + if (WIFSIGNALED(fsrv->child_status) && !*stop_soon_p) { fsrv->last_kill_signal = WTERMSIG(fsrv->child_status); diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 34456c0d..60c9684c 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -418,6 +418,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { (u8 *)get_afl_env(afl_environment_variables[i]); #endif + } else if (!strncmp(env, "AFL_KILL_SIGNAL", + + afl_environment_variable_len)) { + + afl->afl_env.afl_kill_signal = + (u8 *)get_afl_env(afl_environment_variables[i]); + } } else { @@ -524,8 +531,8 @@ void afl_states_stop(void) { LIST_FOREACH(&afl_states, afl_state_t, { - if (el->fsrv.child_pid > 0) kill(el->fsrv.child_pid, SIGKILL); - if (el->fsrv.fsrv_pid > 0) kill(el->fsrv.fsrv_pid, SIGKILL); + if (el->fsrv.child_pid > 0) kill(el->fsrv.child_pid, el->fsrv.kill_signal); + if (el->fsrv.fsrv_pid > 0) kill(el->fsrv.fsrv_pid, el->fsrv.kill_signal); }); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 063134fb..00625f2e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -76,8 +76,17 @@ static void at_exit() { } - if (pid1 > 0) { kill(pid1, SIGKILL); } - if (pid2 > 0) { kill(pid2, SIGKILL); } + u8 kill_signal = SIGKILL; + + /* AFL_KILL_SIGNAL should already be initialized by afl_fsrv_init() */ + if (getenv("AFL_KILL_SIGNAL")) { + + kill_signal = atoi(getenv("AFL_KILL_SIGNAL")); + + } + + if (pid1 > 0) { kill(pid1, kill_signal); } + if (pid2 > 0) { kill(pid2, kill_signal); } } -- cgit v1.2.3 From a06b25538fd7b6eef6755094aa4678c2cb5333fd Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 7 Jan 2021 23:21:10 +0100 Subject: cleaned up AFL_KILL_SIGNAL --- src/afl-forkserver.c | 45 +++++++-------------------------------------- src/afl-fuzz.c | 30 +++++++++++++++++++++++++++++- src/afl-showmap.c | 37 +++++++++++++++++++++++++++++++++---- src/afl-tmin.c | 29 +++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 70fb9572..b7aa87f8 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -84,6 +84,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) { fsrv->init_tmout = EXEC_TIMEOUT * FORK_WAIT_MULT; fsrv->mem_limit = MEM_LIMIT; fsrv->out_file = NULL; + fsrv->kill_signal = SIGKILL; /* exec related stuff */ fsrv->child_pid = -1; @@ -95,30 +96,6 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) { fsrv->uses_asan = false; fsrv->init_child_func = fsrv_exec_child; - fsrv->kill_signal = SIGKILL; - - char *kill_signal_env = get_afl_env("AFL_KILL_SIGNAL"); - if (kill_signal_env) { - - char *endptr; - u8 signal_code; - signal_code = (u8)strtoul(kill_signal_env, &endptr, 10); - /* Did we manage to parse the full string? */ - if (*endptr != '\0' || endptr == kill_signal_env) { - - FATAL("Invalid kill signal value!"); - - } - - fsrv->kill_signal = signal_code; - - } else { - - /* Using hardcoded code for SIGKILL for the sake of simplicity */ - setenv("AFL_KILL_SIGNAL", "9", 1); - - } - list_append(&fsrv_list, fsrv); } @@ -139,6 +116,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->no_unlink = from->no_unlink; fsrv_to->uses_crash_exitcode = from->uses_crash_exitcode; fsrv_to->crash_exitcode = from->crash_exitcode; + fsrv_to->kill_signal = from->kill_signal; // These are forkserver specific. fsrv_to->out_dir_fd = -1; @@ -149,8 +127,6 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->init_child_func = from->init_child_func; // Note: do not copy ->add_extra_func - fsrv_to->kill_signal = from->kill_signal; - list_append(&fsrv_list, fsrv_to); } @@ -1162,25 +1138,18 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, /* Report outcome to caller. */ - /* TODO We use SIGTERM here as an indicator of Xen mode, - although it's not equivalent! */ - if (fsrv->kill_signal == SIGTERM && !*stop_soon_p && - fsrv->last_run_timed_out) { + /* Did we timeout? */ + if (unlikely(fsrv->last_run_timed_out)) { + fsrv->last_kill_signal = fsrv->kill_signal; return FSRV_RUN_TMOUT; } - if (WIFSIGNALED(fsrv->child_status) && !*stop_soon_p) { + /* Did we crash? */ + if (unlikely(WIFSIGNALED(fsrv->child_status) && !*stop_soon_p)) { fsrv->last_kill_signal = WTERMSIG(fsrv->child_status); - - if (fsrv->last_run_timed_out && fsrv->last_kill_signal == SIGKILL) { - - return FSRV_RUN_TMOUT; - - } - return FSRV_RUN_CRASH; } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 00625f2e..5c363c63 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -194,10 +194,11 @@ static void usage(u8 *argv0, int more_help) { "AFL_EXPAND_HAVOC_NOW: immediately enable expand havoc mode (default: after 60 minutes and a cycle without finds)\n" "AFL_FAST_CAL: limit the calibration stage to three cycles for speedup\n" "AFL_FORCE_UI: force showing the status screen (for virtual consoles)\n" - "AFL_HANG_TMOUT: override timeout value (in milliseconds)\n" "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n" + "AFL_HANG_TMOUT: override timeout value (in milliseconds)\n" "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n" "AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n" + "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n" "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n" " the target was compiled for\n" "AFL_MAX_DET_EXTRAS: if more entries are in the dictionary list than this value\n" @@ -986,6 +987,33 @@ int main(int argc, char **argv_orig, char **envp) { #endif + afl->fsrv.kill_signal = SIGKILL; + if (afl->afl_env.afl_kill_signal) { + + char *endptr; + u8 signal_code; + signal_code = (u8)strtoul(afl->afl_env.afl_kill_signal, &endptr, 10); + /* Did we manage to parse the full string? */ + if (*endptr != '\0' || endptr == (char *)afl->afl_env.afl_kill_signal) { + + FATAL("Invalid AFL_KILL_SIGNAL: %s (expected unsigned int)", + afl->afl_env.afl_kill_signal); + + } + + afl->fsrv.kill_signal = signal_code; + + } else { + + char *sigstr = alloc_printf("%d", (int)SIGKILL); + if (!sigstr) { FATAL("Failed to alloc mem for signal buf"); } + + /* Set the env for signal handler */ + setenv("AFL_KILL_SIGNAL", sigstr, 1); + free(sigstr); + + } + setup_signal_handlers(); check_asan_opts(afl); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index d50601fc..2c9c38ed 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -693,12 +693,13 @@ static void usage(u8 *argv0) { "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as " "crash\n" "AFL_DEBUG: enable extra developer output\n" - "AFL_MAP_SIZE: the shared memory size for that target. must be >= the " - "size\n" - " the target was compiled for\n" - "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during " "startup (in milliseconds)\n" + "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, " + "etc. (default: SIGKILL)\n" + "AFL_MAP_SIZE: the shared memory size for that target. must be >= the " + "size the target was compiled for\n" + "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" "AFL_QUIET: do not print extra informational output\n", argv0, MEM_LIMIT, doc_path); @@ -1115,6 +1116,34 @@ int main(int argc, char **argv_orig, char **envp) { } + fsrv->kill_signal = SIGKILL; + char *afl_kill_signal_env = getenv("AFL_KILL_SIGNAL"); + if (afl_kill_signal_env && afl_kill_signal_env[0]) { + + char *endptr; + u8 signal_code; + signal_code = (u8)strtoul(afl_kill_signal_env, &endptr, 10); + /* Did we manage to parse the full string? */ + if (*endptr != '\0' || endptr == afl_kill_signal_env) { + + FATAL("Invalid AFL_KILL_SIGNAL: %s (expected unsigned int)", + afl_kill_signal_env); + + } + + fsrv->kill_signal = signal_code; + + } else { + + char *sigstr = alloc_printf("%d", (int)SIGKILL); + if (!sigstr) { FATAL("Failed to alloc mem for signal buf"); } + + /* Set the env for signal handler */ + setenv("AFL_KILL_SIGNAL", sigstr, 1); + free(sigstr); + + } + if (getenv("AFL_CRASH_EXITCODE")) { long exitcode = strtol(getenv("AFL_CRASH_EXITCODE"), NULL, 10); diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 09d97f58..342de9c8 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -855,6 +855,7 @@ static void usage(u8 *argv0) { "Environment variables used:\n" "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n" "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n" + "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n" "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n" " the target was compiled for\n" "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" @@ -1134,6 +1135,34 @@ int main(int argc, char **argv_orig, char **envp) { } + fsrv->kill_signal = SIGKILL; + char *afl_kill_signal_env = getenv("AFL_KILL_SIGNAL"); + if (afl_kill_signal_env && afl_kill_signal_env[0]) { + + char *endptr; + u8 signal_code; + signal_code = (u8)strtoul(afl_kill_signal_env, &endptr, 10); + /* Did we manage to parse the full string? */ + if (*endptr != '\0' || endptr == afl_kill_signal_env) { + + FATAL("Invalid AFL_KILL_SIGNAL: %s (expected unsigned int)", + afl_kill_signal_env); + + } + + fsrv->kill_signal = signal_code; + + } else { + + char *sigstr = alloc_printf("%d", (int)SIGKILL); + if (!sigstr) { FATAL("Failed to alloc mem for signal buf"); } + + /* Set the env for signal handler */ + setenv("AFL_KILL_SIGNAL", sigstr, 1); + free(sigstr); + + } + if (getenv("AFL_CRASH_EXITCODE")) { long exitcode = strtol(getenv("AFL_CRASH_EXITCODE"), NULL, 10); -- cgit v1.2.3 From 7b8c8cf12fde0feab25a1d794e010a5778cf9be8 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 8 Jan 2021 00:47:52 +0100 Subject: fix --- src/afl-fuzz-queue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index de750f36..c375703d 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -56,7 +56,7 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q, } if (likely(afl->schedule < RARE)) { weight *= (avg_exec_us / q->exec_us); } - weight *= (q->bitmap_size / avg_bitmap_size); + weight *= (log(q->bitmap_size) / avg_bitmap_size); weight *= (log(q->tc_ref) / avg_top_size); if (unlikely(q->favored)) weight *= 5; @@ -103,7 +103,7 @@ void create_alias_table(afl_state_t *afl) { if (likely(!q->disabled)) { avg_exec_us += q->exec_us; - avg_bitmap_size += q->bitmap_size; + avg_bitmap_size += log(q->bitmap_size); avg_top_size += log(q->tc_ref); ++active; -- cgit v1.2.3 From 34732e3c5ede9020ff1802f0f0827e3731217dce Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 8 Jan 2021 11:36:40 +0100 Subject: refactored kill signal env parsing --- src/afl-common.c | 34 ++++++++++++++++++++++++++++++++++ src/afl-fuzz.c | 32 ++++---------------------------- src/afl-showmap.c | 29 ++--------------------------- src/afl-tmin.c | 29 ++--------------------------- 4 files changed, 42 insertions(+), 82 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 21cb6ab4..3a7d0ce5 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -424,6 +424,40 @@ u8 *find_binary(u8 *fname) { } +/* Parses the kill signal environment variable, FATALs on error. + If the env is not set, sets the env to default_signal for the signal handlers + and returns the default_signal. */ +int parse_afl_kill_signal_env(u8 *afl_kill_signal_env, int default_signal) { + + if (afl_kill_signal_env && afl_kill_signal_env[0]) { + + char *endptr; + u8 signal_code; + signal_code = (u8)strtoul(afl_kill_signal_env, &endptr, 10); + /* Did we manage to parse the full string? */ + if (*endptr != '\0' || endptr == (char *)afl_kill_signal_env) { + + FATAL("Invalid AFL_KILL_SIGNAL: %s (expected unsigned int)", + afl_kill_signal_env); + + } + + return signal_code; + + } else { + + char *sigstr = alloc_printf("%d", default_signal); + if (!sigstr) { FATAL("Failed to alloc mem for signal buf"); } + + /* Set the env for signal handler */ + setenv("AFL_KILL_SIGNAL", sigstr, 1); + free(sigstr); + return default_signal; + + } + +} + void check_environment_vars(char **envp) { if (be_quiet) { return; } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 5c363c63..37f8db8a 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -76,9 +76,9 @@ static void at_exit() { } - u8 kill_signal = SIGKILL; + int kill_signal = SIGKILL; - /* AFL_KILL_SIGNAL should already be initialized by afl_fsrv_init() */ + /* AFL_KILL_SIGNAL should already be a valid int at this point */ if (getenv("AFL_KILL_SIGNAL")) { kill_signal = atoi(getenv("AFL_KILL_SIGNAL")); @@ -987,32 +987,8 @@ int main(int argc, char **argv_orig, char **envp) { #endif - afl->fsrv.kill_signal = SIGKILL; - if (afl->afl_env.afl_kill_signal) { - - char *endptr; - u8 signal_code; - signal_code = (u8)strtoul(afl->afl_env.afl_kill_signal, &endptr, 10); - /* Did we manage to parse the full string? */ - if (*endptr != '\0' || endptr == (char *)afl->afl_env.afl_kill_signal) { - - FATAL("Invalid AFL_KILL_SIGNAL: %s (expected unsigned int)", - afl->afl_env.afl_kill_signal); - - } - - afl->fsrv.kill_signal = signal_code; - - } else { - - char *sigstr = alloc_printf("%d", (int)SIGKILL); - if (!sigstr) { FATAL("Failed to alloc mem for signal buf"); } - - /* Set the env for signal handler */ - setenv("AFL_KILL_SIGNAL", sigstr, 1); - free(sigstr); - - } + afl->fsrv.kill_signal = + parse_afl_kill_signal_env(afl->afl_env.afl_kill_signal, SIGKILL); setup_signal_handlers(); check_asan_opts(afl); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 2c9c38ed..5c9d38e0 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1116,33 +1116,8 @@ int main(int argc, char **argv_orig, char **envp) { } - fsrv->kill_signal = SIGKILL; - char *afl_kill_signal_env = getenv("AFL_KILL_SIGNAL"); - if (afl_kill_signal_env && afl_kill_signal_env[0]) { - - char *endptr; - u8 signal_code; - signal_code = (u8)strtoul(afl_kill_signal_env, &endptr, 10); - /* Did we manage to parse the full string? */ - if (*endptr != '\0' || endptr == afl_kill_signal_env) { - - FATAL("Invalid AFL_KILL_SIGNAL: %s (expected unsigned int)", - afl_kill_signal_env); - - } - - fsrv->kill_signal = signal_code; - - } else { - - char *sigstr = alloc_printf("%d", (int)SIGKILL); - if (!sigstr) { FATAL("Failed to alloc mem for signal buf"); } - - /* Set the env for signal handler */ - setenv("AFL_KILL_SIGNAL", sigstr, 1); - free(sigstr); - - } + fsrv->kill_signal = + parse_afl_kill_signal_env(getenv("AFL_KILL_SIGNAL"), SIGKILL); if (getenv("AFL_CRASH_EXITCODE")) { diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 342de9c8..6e2d7708 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -1135,33 +1135,8 @@ int main(int argc, char **argv_orig, char **envp) { } - fsrv->kill_signal = SIGKILL; - char *afl_kill_signal_env = getenv("AFL_KILL_SIGNAL"); - if (afl_kill_signal_env && afl_kill_signal_env[0]) { - - char *endptr; - u8 signal_code; - signal_code = (u8)strtoul(afl_kill_signal_env, &endptr, 10); - /* Did we manage to parse the full string? */ - if (*endptr != '\0' || endptr == afl_kill_signal_env) { - - FATAL("Invalid AFL_KILL_SIGNAL: %s (expected unsigned int)", - afl_kill_signal_env); - - } - - fsrv->kill_signal = signal_code; - - } else { - - char *sigstr = alloc_printf("%d", (int)SIGKILL); - if (!sigstr) { FATAL("Failed to alloc mem for signal buf"); } - - /* Set the env for signal handler */ - setenv("AFL_KILL_SIGNAL", sigstr, 1); - free(sigstr); - - } + fsrv->kill_signal = + parse_afl_kill_signal_env(getenv("AFL_KILL_SIGNAL"), SIGKILL); if (getenv("AFL_CRASH_EXITCODE")) { -- cgit v1.2.3 From 3d1a25ce4e8862b82662c64fbea000692f300c62 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 8 Jan 2021 11:54:35 +0100 Subject: added check to silence scan-build --- src/afl-fuzz-run.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 41557707..cc2ef891 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -430,6 +430,13 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, /* OK, let's collect some stats about the performance of this test case. This is used for fuzzing air time calculations in calculate_score(). */ + if (unlikely(!afl->stage_max)) { + + // Pretty sure this cannot happen, yet scan-build complains. + FATAL("BUG: stage_max should not be 0 here! Please report this condition."); + + } + q->exec_us = (stop_us - start_us) / afl->stage_max; q->bitmap_size = count_bytes(afl, afl->fsrv.trace_bits); q->handicap = handicap; -- cgit v1.2.3 From 3196a5f666acc29e42e8e5e49099bab4a7b2deba Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 8 Jan 2021 18:17:52 +0100 Subject: cleaned up and added comments to forkserver exits --- src/afl-forkserver.c | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index b7aa87f8..413676bf 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1138,38 +1138,43 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, /* Report outcome to caller. */ - /* Did we timeout? */ - if (unlikely(fsrv->last_run_timed_out)) { + /* Was the run unsuccessful? */ + if (unlikely(*(u32 *)fsrv->trace_bits == EXEC_FAIL_SIG)) { - fsrv->last_kill_signal = fsrv->kill_signal; - return FSRV_RUN_TMOUT; + return FSRV_RUN_ERROR; } - /* Did we crash? */ - if (unlikely(WIFSIGNALED(fsrv->child_status) && !*stop_soon_p)) { + /* Did we timeout? */ + if (unlikely(fsrv->last_run_timed_out)) { - fsrv->last_kill_signal = WTERMSIG(fsrv->child_status); - return FSRV_RUN_CRASH; + fsrv->last_kill_signal = fsrv->kill_signal; + return FSRV_RUN_TMOUT; } - /* MSAN in uses_asan mode uses a special exit code as it doesn't support - abort_on_error. - On top, a user may specify a custom AFL_CRASH_EXITCODE. Handle both here. */ - - if ((fsrv->uses_asan && WEXITSTATUS(fsrv->child_status) == MSAN_ERROR) || - (fsrv->uses_crash_exitcode && - WEXITSTATUS(fsrv->child_status) == fsrv->crash_exitcode)) { - - fsrv->last_kill_signal = 0; + /* Did we crash? + In a normal case, (abort) WIFSIGNALED(child_status) will be set. + MSAN in uses_asan mode uses a special exit code as it doesn't support + abort_on_error. On top, a user may specify a custom AFL_CRASH_EXITCODE. + Handle all three cases here. */ + + if (unlikely( + /* A normal crash/abort */ + (WIFSIGNALED(fsrv->child_status)) || + /* special handling for msan */ + (fsrv->uses_asan && WEXITSTATUS(fsrv->child_status) == MSAN_ERROR) || + /* the custom crash_exitcode was returned by the target */ + (fsrv->uses_crash_exitcode && + WEXITSTATUS(fsrv->child_status) == fsrv->crash_exitcode))) { + + /* 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; } - // Fauxserver should handle this now. - if (*(u32 *)fsrv->trace_bits == EXEC_FAIL_SIG) return FSRV_RUN_ERROR; - + /* success :) */ return FSRV_RUN_OK; } -- cgit v1.2.3 From 4581ad3df9a3e98b065c61d1f392398973669479 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 8 Jan 2021 18:19:40 +0100 Subject: code fmt --- src/afl-forkserver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 413676bf..b6b3cd74 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1169,7 +1169,8 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, WEXITSTATUS(fsrv->child_status) == fsrv->crash_exitcode))) { /* 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; + fsrv->last_kill_signal = + WIFSIGNALED(fsrv->child_status) ? WTERMSIG(fsrv->child_status) : 0; return FSRV_RUN_CRASH; } -- cgit v1.2.3 From dc81f681c9cb0af66ae6f820ed421a2b7100a404 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 10 Jan 2021 13:12:44 +0100 Subject: fix weight calc, thanks to Marcel --- src/afl-fuzz-queue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 99f564e9..66938635 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -57,7 +57,7 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q, if (likely(afl->schedule < RARE)) { weight *= (avg_exec_us / q->exec_us); } weight *= (log(q->bitmap_size) / avg_bitmap_size); - weight *= (log(q->tc_ref) / avg_top_size); + weight *= (1 + (q->tc_ref / avg_top_size)); if (unlikely(q->favored)) weight *= 5; return weight; @@ -104,7 +104,7 @@ void create_alias_table(afl_state_t *afl) { avg_exec_us += q->exec_us; avg_bitmap_size += log(q->bitmap_size); - avg_top_size += log(q->tc_ref); + avg_top_size += q->tc_ref; ++active; } -- cgit v1.2.3 From efd80424311147523c0aa4f6436066771788dc44 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 12 Jan 2021 13:42:00 +0100 Subject: fix lto cmplog instability --- src/afl-fuzz-run.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index cc2ef891..bded8e2d 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -296,11 +296,11 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at, u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, u32 handicap, u8 from_queue) { + if (unlikely(afl->shm.cmplog_mode)) { q->exec_cksum = 0; } + u8 fault = 0, new_bits = 0, var_detected = 0, hnb = 0, first_run = (q->exec_cksum == 0); - u64 start_us, stop_us; - s32 old_sc = afl->stage_cur, old_sm = afl->stage_max; u32 use_tmout = afl->fsrv.exec_tmout; u8 *old_sn = afl->stage_name; -- cgit v1.2.3 From b9ba2805e537f8033075f90f31b52767f31267dc Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 12 Jan 2021 17:31:29 +0100 Subject: minor changes --- src/afl-forkserver.c | 4 ++-- src/afl-fuzz-run.c | 22 ++++++++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index b6b3cd74..7535720d 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -972,10 +972,10 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { hash64(fsrv->shmem_fuzz, *fsrv->shmem_fuzz_len, 0xa5b35705), *fsrv->shmem_fuzz_len); fprintf(stderr, "SHM :"); - for (int i = 0; i < *fsrv->shmem_fuzz_len; i++) + for (u32 i = 0; i < *fsrv->shmem_fuzz_len; i++) fprintf(stderr, "%02x", fsrv->shmem_fuzz[i]); fprintf(stderr, "\nORIG:"); - for (int i = 0; i < *fsrv->shmem_fuzz_len; i++) + for (u32 i = 0; i < *fsrv->shmem_fuzz_len; i++) fprintf(stderr, "%02x", buf[i]); fprintf(stderr, "\n"); diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index bded8e2d..b597488b 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -230,10 +230,10 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at, hash64(afl->fsrv.shmem_fuzz, *afl->fsrv.shmem_fuzz_len, 0xa5b35705), *afl->fsrv.shmem_fuzz_len); fprintf(stderr, "SHM :"); - for (int i = 0; i < *afl->fsrv.shmem_fuzz_len; i++) + for (u32 i = 0; i < *afl->fsrv.shmem_fuzz_len; i++) fprintf(stderr, "%02x", afl->fsrv.shmem_fuzz[i]); fprintf(stderr, "\nORIG:"); - for (int i = 0; i < *afl->fsrv.shmem_fuzz_len; i++) + for (u32 i = 0; i < *afl->fsrv.shmem_fuzz_len; i++) fprintf(stderr, "%02x", (u8)((u8 *)mem)[i]); fprintf(stderr, "\n"); @@ -300,7 +300,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, u8 fault = 0, new_bits = 0, var_detected = 0, hnb = 0, first_run = (q->exec_cksum == 0); - u64 start_us, stop_us; + u64 start_us, stop_us, diff_us; s32 old_sc = afl->stage_cur, old_sm = afl->stage_max; u32 use_tmout = afl->fsrv.exec_tmout; u8 *old_sn = afl->stage_name; @@ -422,9 +422,19 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, } - stop_us = get_cur_time_us(); + if (unlikely(afl->fixed_seed)) { - afl->total_cal_us += stop_us - start_us; + diff_us = (afl->fsrv.exec_tmout - 1) * afl->stage_max; + + } else { + + stop_us = get_cur_time_us(); + diff_us = stop_us - start_us; + if (unlikely(!diff_us)) { ++diff_us; } + + } + + afl->total_cal_us += diff_us; afl->total_cal_cycles += afl->stage_max; /* OK, let's collect some stats about the performance of this test case. @@ -437,7 +447,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, } - q->exec_us = (stop_us - start_us) / afl->stage_max; + q->exec_us = diff_us / afl->stage_max; q->bitmap_size = count_bytes(afl, afl->fsrv.trace_bits); q->handicap = handicap; q->cal_failed = 0; -- cgit v1.2.3 From 0ddbffd80e6378bdaf8565caeca3990630574d3f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 12 Jan 2021 17:36:10 +0100 Subject: fix --- src/afl-common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 3a7d0ce5..cf996548 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -927,14 +927,14 @@ u32 get_map_size(void) { if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) { map_size = atoi(ptr); - if (map_size < 8 || map_size > (1 << 29)) { + if (!map_size || map_size > (1 << 29)) { - FATAL("illegal AFL_MAP_SIZE %u, must be between %u and %u", map_size, 8U, + FATAL("illegal AFL_MAP_SIZE %u, must be between %u and %u", map_size, 32U, 1U << 29); } - if (map_size % 8) { map_size = (((map_size >> 3) + 1) << 3); } + if (map_size % 32) { map_size = (((map_size >> 5) + 1) << 5); } } -- cgit v1.2.3 From 53c7aaa57bf5473c5d6a4553c0178410fef17cbc Mon Sep 17 00:00:00 2001 From: murx- Date: Thu, 14 Jan 2021 13:46:03 +0100 Subject: Update documentation to reflect new default power schedule --- src/afl-fuzz.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 37f8db8a..6a2b28cf 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -103,8 +103,8 @@ static void usage(u8 *argv0, int more_help) { "Execution control settings:\n" " -p schedule - power schedules compute a seed's performance score:\n" - " -- see docs/power_schedules.md\n" " -f file - location read by the fuzzed program (default: stdin " "or @@)\n" -- cgit v1.2.3 From 7ba17d182f7010c616fe9ecf4ba291cd772f52bc Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 14 Jan 2021 21:26:46 +0100 Subject: more sync in deterministic mode --- src/afl-fuzz.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 6a2b28cf..bb2674f0 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1781,15 +1781,27 @@ int main(int argc, char **argv_orig, char **envp) { } while (skipped_fuzz && afl->queue_cur && !afl->stop_soon); - if (!afl->stop_soon && afl->sync_id) { + if (likely(!afl->stop_soon && afl->sync_id)) { - if (unlikely(afl->is_main_node)) { + if (likely(afl->skip_deterministic)) { - if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) { sync_fuzzers(afl); } + if (unlikely(afl->is_main_node)) { + + if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) { + + sync_fuzzers(afl); + + } + + } else { + + if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); } + + } } else { - if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); } + sync_fuzzers(afl); } -- cgit v1.2.3 From d5049da5e4d8ab7d0ec594cc9440437deba861bb Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 15 Jan 2021 14:50:51 +0100 Subject: better error message --- src/afl-forkserver.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 7535720d..39f044f2 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -808,6 +808,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "before receiving any input\n" " from the fuzzer! There are several probable explanations:\n\n" + " - The target binary requires a large map and crashes before " + "reporting.\n" + " Set a high value (e.g. AFL_MAP_SIZE=1024000) or use " + "AFL_DEBUG=1 to see the\n" + " message from the target binary\n\n" + " - The binary is just buggy and explodes entirely on its own. " "If so, you\n" " need to fix the underlying problem or find a better " @@ -829,6 +835,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "before receiving any input\n" " from the fuzzer! There are several probable explanations:\n\n" + " - The target binary requires a large map and crashes before " + "reporting.\n" + " Set a high value (e.g. AFL_MAP_SIZE=1024000) or use " + "AFL_DEBUG=1 to see the\n" + " message from the target binary\n\n" + " - The current memory limit (%s) is too restrictive, causing " "the\n" " target to hit an OOM condition in the dynamic linker. Try " -- cgit v1.2.3 From 8eb00a5dfab01330f576d173038a9561951371ec Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 15 Jan 2021 14:55:58 +0100 Subject: remove warning --- src/afl-cc.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 999ee7f1..8fb42718 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1785,15 +1785,6 @@ int main(int argc, char **argv, char **envp) { } - if (!be_quiet && !lto_mode && - ((ptr2 = getenv("AFL_MAP_SIZE")) || (ptr2 = getenv("AFL_MAPSIZE")))) { - - u32 map_size = atoi(ptr2); - if (map_size != MAP_SIZE) - WARNF("AFL_MAP_SIZE is not supported by afl-clang-fast"); - - } - if (debug) { DEBUGF("cd '%s';", getthecwd()); -- cgit v1.2.3 From a0e884cf8bffe1a0394d106375f6a23edd2b60e6 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 15 Jan 2021 16:56:40 +0100 Subject: merge cmplog --- src/afl-cc.c | 49 +- src/afl-fuzz-init.c | 38 ++ src/afl-fuzz-one.c | 81 ++- src/afl-fuzz-queue.c | 1 + src/afl-fuzz-redqueen.c | 1437 ++++++++++++++++++++++++++++++++++++++++------- src/afl-fuzz-state.c | 1 + src/afl-fuzz.c | 60 +- 7 files changed, 1399 insertions(+), 268 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 8fb42718..02c9c7c5 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -528,10 +528,10 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = alloc_printf( "-Wl,-mllvm=-load=%s/cmplog-routines-pass.so", obj_path); - cc_params[cc_par_cnt++] = alloc_printf( - "-Wl,-mllvm=-load=%s/split-switches-pass.so", obj_path); cc_params[cc_par_cnt++] = alloc_printf( "-Wl,-mllvm=-load=%s/cmplog-instructions-pass.so", obj_path); + cc_params[cc_par_cnt++] = alloc_printf( + "-Wl,-mllvm=-load=%s/split-switches-pass.so", obj_path); } else { @@ -541,18 +541,18 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = alloc_printf("%s/cmplog-routines-pass.so", obj_path); - // reuse split switches from laf cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = - alloc_printf("%s/split-switches-pass.so", obj_path); + alloc_printf("%s/cmplog-instructions-pass.so", obj_path); + // reuse split switches from laf cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = - alloc_printf("%s/cmplog-instructions-pass.so", obj_path); + alloc_printf("%s/split-switches-pass.so", obj_path); } @@ -792,10 +792,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { } -#if defined(USEMMAP) - #if !defined(__HAIKU__) +#if defined(USEMMAP) && !defined(__HAIKU__) cc_params[cc_par_cnt++] = "-lrt"; - #endif #endif cc_params[cc_par_cnt++] = "-D__AFL_HAVE_MANUAL_CONTROL=1"; @@ -858,6 +856,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_DISCARD()=__afl_coverage_discard()"; cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_ABORT()=__afl_coverage_abort()"; + cc_params[cc_par_cnt++] = "-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : " "__afl_fuzz_alt_ptr)"; @@ -967,10 +966,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); #endif - #if defined(USEMMAP) - #if !defined(__HAIKU__) + #if defined(USEMMAP) && !defined(__HAIKU__) cc_params[cc_par_cnt++] = "-lrt"; - #endif #endif } @@ -1278,7 +1275,6 @@ int main(int argc, char **argv, char **envp) { } - // this is a hidden option if (strncasecmp(ptr2, "llvmnative", strlen("llvmnative")) == 0 || strncasecmp(ptr2, "llvm-native", strlen("llvm-native")) == 0) { @@ -1349,29 +1345,28 @@ int main(int argc, char **argv, char **envp) { if (strncasecmp(ptr2, "ngram", strlen("ngram")) == 0) { - ptr2 += strlen("ngram"); - while (*ptr2 && (*ptr2 < '0' || *ptr2 > '9')) - ptr2++; + u8 *ptr3 = ptr2 + strlen("ngram"); + while (*ptr3 && (*ptr3 < '0' || *ptr3 > '9')) + ptr3++; - if (!*ptr2) { + if (!*ptr3) { - if ((ptr2 = getenv("AFL_LLVM_NGRAM_SIZE")) == NULL) + if ((ptr3 = getenv("AFL_LLVM_NGRAM_SIZE")) == NULL) FATAL( "you must set the NGRAM size with (e.g. for value 2) " "AFL_LLVM_INSTRUMENT=ngram-2"); } - ngram_size = atoi(ptr2); + ngram_size = atoi(ptr3); if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX) FATAL( "NGRAM instrumentation option must be between 2 and " - "NGRAM_SIZE_MAX " - "(%u)", + "NGRAM_SIZE_MAX (%u)", NGRAM_SIZE_MAX); instrument_opt_mode |= (INSTRUMENT_OPT_NGRAM); - ptr2 = alloc_printf("%u", ngram_size); - setenv("AFL_LLVM_NGRAM_SIZE", ptr2, 1); + u8 *ptr4 = alloc_printf("%u", ngram_size); + setenv("AFL_LLVM_NGRAM_SIZE", ptr4, 1); } @@ -1507,6 +1502,7 @@ int main(int argc, char **argv, char **envp) { "((instrumentation/README.ngram.md)\n" " INSTRIM: Dominator tree (for LLVM <= 6.0) " "(instrumentation/README.instrim.md)\n\n"); + #undef NATIVE_MSG SAYF( @@ -1641,16 +1637,15 @@ int main(int argc, char **argv, char **envp) { if (have_lto) SAYF("afl-cc LTO with ld=%s %s\n", AFL_REAL_LD, AFL_CLANG_FLTO); if (have_llvm) - SAYF("afl-cc LLVM version %d using binary path \"%s\".\n", LLVM_MAJOR, + SAYF("afl-cc LLVM version %d using the binary path \"%s\".\n", LLVM_MAJOR, LLVM_BINDIR); #endif -#if defined(USEMMAP) +#ifdef USEMMAP #if !defined(__HAIKU__) - cc_params[cc_par_cnt++] = "-lrt"; - SAYF("Compiled with shm_open support (adds -lrt when linking).\n"); - #else SAYF("Compiled with shm_open support.\n"); + #else + SAYF("Compiled with shm_open support (adds -lrt when linking).\n"); #endif #else SAYF("Compiled with shmat support.\n"); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index dbffa4f9..cbff6d7e 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -729,6 +729,30 @@ void read_testcases(afl_state_t *afl, u8 *directory) { add_to_queue(afl, fn2, st.st_size >= MAX_FILE ? MAX_FILE : st.st_size, passed_det); + if (unlikely(afl->shm.cmplog_mode)) { + + if (afl->cmplog_lvl == 1) { + + if (!afl->cmplog_max_filesize || + afl->cmplog_max_filesize < st.st_size) { + + afl->cmplog_max_filesize = st.st_size; + + } + + } else if (afl->cmplog_lvl == 2) { + + if (!afl->cmplog_max_filesize || + afl->cmplog_max_filesize > st.st_size) { + + afl->cmplog_max_filesize = st.st_size; + + } + + } + + } + if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); @@ -756,6 +780,20 @@ void read_testcases(afl_state_t *afl, u8 *directory) { } + if (unlikely(afl->shm.cmplog_mode)) { + + if (afl->cmplog_max_filesize < 1024) { + + afl->cmplog_max_filesize = 1024; + + } else { + + afl->cmplog_max_filesize = (((afl->cmplog_max_filesize >> 10) + 1) << 10); + + } + + } + afl->last_path_time = 0; afl->queued_at_start = afl->queued_paths; diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index f9509e86..596bae22 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -165,7 +165,7 @@ static u8 could_be_arith(u32 old_val, u32 new_val, u8 blen) { /* See if one-byte adjustments to any byte could produce this result. */ - for (i = 0; i < blen; ++i) { + for (i = 0; (u8)i < blen; ++i) { u8 a = old_val >> (8 * i), b = new_val >> (8 * i); @@ -193,7 +193,7 @@ static u8 could_be_arith(u32 old_val, u32 new_val, u8 blen) { diffs = 0; - for (i = 0; i < blen / 2; ++i) { + for (i = 0; (u8)i < blen / 2; ++i) { u16 a = old_val >> (16 * i), b = new_val >> (16 * i); @@ -290,7 +290,7 @@ static u8 could_be_interest(u32 old_val, u32 new_val, u8 blen, u8 check_le) { /* See if two-byte insertions over old_val could give us new_val. */ - for (i = 0; (s32)i < blen - 1; ++i) { + for (i = 0; (u8)i < blen - 1; ++i) { for (j = 0; j < sizeof(interesting_16) / 2; ++j) { @@ -545,14 +545,31 @@ u8 fuzz_one_original(afl_state_t *afl) { else orig_perf = perf_score = calculate_score(afl, afl->queue_cur); - if (unlikely(perf_score == 0)) { goto abandon_entry; } + if (unlikely(perf_score <= 0)) { goto abandon_entry; } - if (unlikely(afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized)) { + if (unlikely(afl->shm.cmplog_mode && + afl->queue_cur->colorized < afl->cmplog_lvl && + (u32)len <= afl->cmplog_max_filesize)) { - if (input_to_state_stage(afl, in_buf, out_buf, len, - afl->queue_cur->exec_cksum)) { + if (unlikely(len < 4)) { - goto abandon_entry; + afl->queue_cur->colorized = 0xff; + + } else { + + if (afl->cmplog_lvl == 3 || + (afl->cmplog_lvl == 2 && afl->queue_cur->tc_ref) || + !(afl->fsrv.total_execs % afl->queued_paths) || + get_cur_time() - afl->last_path_time > 15000) { + + if (input_to_state_stage(afl, in_buf, out_buf, len, + afl->queue_cur->exec_cksum)) { + + goto abandon_entry; + + } + + } } @@ -2796,7 +2813,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { } - s32 len, temp_len; + u32 len, temp_len; u32 i; u32 j; u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0; @@ -2952,14 +2969,31 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { else orig_perf = perf_score = calculate_score(afl, afl->queue_cur); - if (unlikely(perf_score == 0)) { goto abandon_entry; } + if (unlikely(perf_score <= 0)) { goto abandon_entry; } - if (unlikely(afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized)) { + if (unlikely(afl->shm.cmplog_mode && + afl->queue_cur->colorized < afl->cmplog_lvl && + (u32)len <= afl->cmplog_max_filesize)) { - if (input_to_state_stage(afl, in_buf, out_buf, len, - afl->queue_cur->exec_cksum)) { + if (unlikely(len < 4)) { - goto abandon_entry; + afl->queue_cur->colorized = 0xff; + + } else { + + if (afl->cmplog_lvl == 3 || + (afl->cmplog_lvl == 2 && afl->queue_cur->tc_ref) || + !(afl->fsrv.total_execs % afl->queued_paths) || + get_cur_time() - afl->last_path_time > 15000) { + + if (input_to_state_stage(afl, in_buf, out_buf, len, + afl->queue_cur->exec_cksum)) { + + goto abandon_entry; + + } + + } } @@ -3315,7 +3349,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { orig_hit_cnt = new_hit_cnt; - for (i = 0; (s32)i < len - 1; ++i) { + for (i = 0; i < len - 1; ++i) { /* Let's consult the effector map... */ @@ -3357,7 +3391,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { orig_hit_cnt = new_hit_cnt; - for (i = 0; (s32)i < len - 3; ++i) { + for (i = 0; i < len - 3; ++i) { /* Let's consult the effector map... */ if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] && @@ -3489,7 +3523,7 @@ skip_bitflip: orig_hit_cnt = new_hit_cnt; - for (i = 0; (s32)i < len - 1; ++i) { + for (i = 0; i < len - 1; ++i) { u16 orig = *(u16 *)(out_buf + i); @@ -3615,7 +3649,7 @@ skip_bitflip: orig_hit_cnt = new_hit_cnt; - for (i = 0; (s32)i < len - 3; ++i) { + for (i = 0; i < len - 3; ++i) { u32 orig = *(u32 *)(out_buf + i); @@ -3805,7 +3839,7 @@ skip_arith: orig_hit_cnt = new_hit_cnt; - for (i = 0; (s32)i < len - 1; ++i) { + for (i = 0; i < len - 1; ++i) { u16 orig = *(u16 *)(out_buf + i); @@ -3891,7 +3925,7 @@ skip_arith: orig_hit_cnt = new_hit_cnt; - for (i = 0; (s32)i < len - 3; ++i) { + for (i = 0; i < len - 3; ++i) { u32 orig = *(u32 *)(out_buf + i); @@ -4120,7 +4154,7 @@ skip_user_extras: /* See the comment in the earlier code; extras are sorted by size. */ - if ((s32)(afl->a_extras[j].len) > (s32)(len - i) || + if ((afl->a_extras[j].len) > (len - i) || !memcmp(afl->a_extras[j].data, out_buf + i, afl->a_extras[j].len) || !memchr(eff_map + EFF_APOS(i), 1, EFF_SPAN_ALEN(i, afl->a_extras[j].len))) { @@ -4837,7 +4871,7 @@ pacemaker_fuzzing: u32 copy_from, copy_to, copy_len; copy_len = choose_block_len(afl, new_len - 1); - if ((s32)copy_len > temp_len) copy_len = temp_len; + if (copy_len > temp_len) copy_len = temp_len; copy_from = rand_below(afl, new_len - copy_len + 1); copy_to = rand_below(afl, temp_len - copy_len + 1); @@ -5033,8 +5067,7 @@ pacemaker_fuzzing: the last differing byte. Bail out if the difference is just a single byte or so. */ - locate_diffs(in_buf, new_buf, MIN(len, (s32)target->len), &f_diff, - &l_diff); + locate_diffs(in_buf, new_buf, MIN(len, target->len), &f_diff, &l_diff); if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) { diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 66938635..aec57a6e 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -433,6 +433,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { q->passed_det = passed_det; q->trace_mini = NULL; q->testcase_buf = NULL; + q->mother = afl->queue_cur; #ifdef INTROSPECTION q->bitsmap_size = afl->bitsmap_size; diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 28585afe..955a9232 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -28,6 +28,8 @@ #include "afl-fuzz.h" #include "cmplog.h" +//#define _DEBUG + ///// Colorization struct range { @@ -35,6 +37,8 @@ struct range { u32 start; u32 end; struct range *next; + struct range *prev; + u8 ok; }; @@ -44,6 +48,8 @@ static struct range *add_range(struct range *ranges, u32 start, u32 end) { r->start = start; r->end = end; r->next = ranges; + r->ok = 0; + if (likely(ranges)) ranges->prev = r; return r; } @@ -51,45 +57,61 @@ static struct range *add_range(struct range *ranges, u32 start, u32 end) { static struct range *pop_biggest_range(struct range **ranges) { struct range *r = *ranges; - struct range *prev = NULL; struct range *rmax = NULL; - struct range *prev_rmax = NULL; u32 max_size = 0; while (r) { - u32 s = r->end - r->start; - if (s >= max_size) { + if (!r->ok) { + + u32 s = 1 + r->end - r->start; + + if (s >= max_size) { + + max_size = s; + rmax = r; - max_size = s; - prev_rmax = prev; - rmax = r; + } } - prev = r; r = r->next; } - if (rmax) { + return rmax; - if (prev_rmax) { +} - prev_rmax->next = rmax->next; +#ifdef _DEBUG +// static int logging = 0; +static void dump(char *txt, u8 *buf, u32 len) { - } else { + u32 i; + fprintf(stderr, "DUMP %s %llx ", txt, hash64(buf, len, 0)); + for (i = 0; i < len; i++) + fprintf(stderr, "%02x", buf[i]); + fprintf(stderr, "\n"); - *ranges = rmax->next; +} - } +static void dump_file(char *path, char *name, u32 counter, u8 *buf, u32 len) { - } + char fn[4096]; + if (!path) path = "."; + snprintf(fn, sizeof(fn), "%s/%s%d", path, name, counter); + int fd = open(fn, O_RDWR | O_CREAT | O_TRUNC, 0644); + if (fd >= 0) { - return rmax; + write(fd, buf, len); + close(fd); + + } } +#endif + static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u64 *cksum) { if (unlikely(common_fuzz_stuff(afl, buf, len))) { return 1; } @@ -99,107 +121,270 @@ static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u64 *cksum) { } -static void xor_replace(u8 *buf, u32 len) { +/* replace everything with different values but stay in the same type */ +static void type_replace(afl_state_t *afl, u8 *buf, u32 len) { u32 i; + u8 c; for (i = 0; i < len; ++i) { - buf[i] ^= 0xff; + // wont help for UTF or non-latin charsets + do { + + switch (buf[i]) { + + case 'A' ... 'F': + c = 'A' + rand_below(afl, 1 + 'F' - 'A'); + break; + case 'a' ... 'f': + c = 'a' + rand_below(afl, 1 + 'f' - 'a'); + break; + case '0': + c = '1'; + break; + case '1': + c = '0'; + break; + case '2' ... '9': + c = '2' + rand_below(afl, 1 + '9' - '2'); + break; + case 'G' ... 'Z': + c = 'G' + rand_below(afl, 1 + 'Z' - 'G'); + break; + case 'g' ... 'z': + c = 'g' + rand_below(afl, 1 + 'z' - 'g'); + break; + case '!' ... '*': + c = '!' + rand_below(afl, 1 + '*' - '!'); + break; + case ',' ... '.': + c = ',' + rand_below(afl, 1 + '.' - ','); + break; + case ':' ... '@': + c = ':' + rand_below(afl, 1 + '@' - ':'); + break; + case '[' ... '`': + c = '[' + rand_below(afl, 1 + '`' - '['); + break; + case '{' ... '~': + c = '{' + rand_below(afl, 1 + '~' - '{'); + break; + case '+': + c = '/'; + break; + case '/': + c = '+'; + break; + case ' ': + c = '\t'; + break; + case '\t': + c = ' '; + break; + /* + case '\r': + case '\n': + // nothing ... + break; + */ + default: + c = (buf[i] ^ 0xff); + + } + + } while (c == buf[i]); + + buf[i] = c; } } -static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) { +static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum, + struct tainted **taints) { - struct range *ranges = add_range(NULL, 0, len); - u8 * backup = ck_alloc_nozero(len); + struct range * ranges = add_range(NULL, 0, len - 1), *rng; + struct tainted *taint = NULL; + u8 * backup = ck_alloc_nozero(len); + u8 * changed = ck_alloc_nozero(len); u64 orig_hit_cnt, new_hit_cnt; orig_hit_cnt = afl->queued_paths + afl->unique_crashes; afl->stage_name = "colorization"; afl->stage_short = "colorization"; - afl->stage_max = 1000; + afl->stage_max = (len << 1); - struct range *rng = NULL; afl->stage_cur = 0; + memcpy(backup, buf, len); + memcpy(changed, buf, len); + type_replace(afl, changed, len); + while ((rng = pop_biggest_range(&ranges)) != NULL && afl->stage_cur < afl->stage_max) { - u32 s = rng->end - rng->start; + u32 s = 1 + rng->end - rng->start; + + memcpy(buf + rng->start, changed + rng->start, s); - if (s != 0) { + u64 cksum; + u64 start_us = get_cur_time_us(); + if (unlikely(get_exec_checksum(afl, buf, len, &cksum))) { - /* Range not empty */ + goto checksum_fail; - memcpy(backup, buf + rng->start, s); - xor_replace(buf + rng->start, s); + } + + u64 stop_us = get_cur_time_us(); + + /* Discard if the mutations change the path or if it is too decremental + in speed - how could the same path have a much different speed + though ...*/ + if (cksum != exec_cksum || + (unlikely(stop_us - start_us > 3 * afl->queue_cur->exec_us) && + likely(!afl->fixed_seed))) { + + memcpy(buf + rng->start, backup + rng->start, s); - u64 cksum; - u64 start_us = get_cur_time_us(); - if (unlikely(get_exec_checksum(afl, buf, len, &cksum))) { + if (s > 1) { // to not add 0 size ranges - goto checksum_fail; + ranges = add_range(ranges, rng->start, rng->start - 1 + s / 2); + ranges = add_range(ranges, rng->start + s / 2, rng->end); } - u64 stop_us = get_cur_time_us(); + if (ranges == rng) { + + ranges = rng->next; + if (ranges) { ranges->prev = NULL; } + + } else if (rng->next) { + + rng->prev->next = rng->next; + rng->next->prev = rng->prev; - /* Discard if the mutations change the paths or if it is too decremental - in speed */ - if (cksum != exec_cksum || - ((stop_us - start_us > 2 * afl->queue_cur->exec_us) && - likely(!afl->fixed_seed))) { + } else { - ranges = add_range(ranges, rng->start, rng->start + s / 2); - ranges = add_range(ranges, rng->start + s / 2 + 1, rng->end); - memcpy(buf + rng->start, backup, s); + if (rng->prev) { rng->prev->next = NULL; } } + free(rng); + + } else { + + rng->ok = 1; + } - ck_free(rng); - rng = NULL; ++afl->stage_cur; } - if (afl->stage_cur < afl->stage_max) { afl->queue_cur->fully_colorized = 1; } + rng = ranges; + while (rng) { - new_hit_cnt = afl->queued_paths + afl->unique_crashes; - afl->stage_finds[STAGE_COLORIZATION] += new_hit_cnt - orig_hit_cnt; - afl->stage_cycles[STAGE_COLORIZATION] += afl->stage_cur; - ck_free(backup); + rng = rng->next; - ck_free(rng); - rng = NULL; + } - while (ranges) { + u32 i = 1; + u32 positions = 0; + while (i) { + restart: + i = 0; + struct range *r = NULL; + u32 pos = (u32)-1; rng = ranges; - ranges = rng->next; - ck_free(rng); - rng = NULL; - } + while (rng) { - return 0; + if (rng->ok == 1 && rng->start < pos) { -checksum_fail: - if (rng) { ck_free(rng); } - ck_free(backup); + if (taint && taint->pos + taint->len == rng->start) { + + taint->len += (1 + rng->end - rng->start); + positions += (1 + rng->end - rng->start); + rng->ok = 2; + goto restart; + + } else { + + r = rng; + pos = rng->start; + + } + + } + + rng = rng->next; + + } + + if (r) { + + struct tainted *t = ck_alloc_nozero(sizeof(struct tainted)); + t->pos = r->start; + t->len = 1 + r->end - r->start; + positions += (1 + r->end - r->start); + if (likely(taint)) { taint->prev = t; } + t->next = taint; + t->prev = NULL; + taint = t; + r->ok = 2; + i = 1; + } + + } + + *taints = taint; + + /* temporary: clean ranges */ while (ranges) { rng = ranges; ranges = rng->next; ck_free(rng); - rng = NULL; } + new_hit_cnt = afl->queued_paths + afl->unique_crashes; + +#ifdef _DEBUG + /* + char fn[4096]; + snprintf(fn, sizeof(fn), "%s/introspection_color.txt", afl->out_dir); + FILE *f = fopen(fn, "a"); + if (f) { + + */ + FILE *f = stderr; + fprintf(f, + "Colorization: fname=%s len=%u result=%u execs=%u found=%llu " + "taint=%u\n", + afl->queue_cur->fname, len, afl->queue_cur->colorized, afl->stage_cur, + new_hit_cnt - orig_hit_cnt, positions); +/* + fclose(f); + + } + +*/ +#endif + + afl->stage_finds[STAGE_COLORIZATION] += new_hit_cnt - orig_hit_cnt; + afl->stage_cycles[STAGE_COLORIZATION] += afl->stage_cur; + ck_free(backup); + ck_free(changed); + + return 0; + +checksum_fail: + ck_free(backup); + ck_free(changed); + return 1; } @@ -212,12 +397,19 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) { orig_hit_cnt = afl->queued_paths + afl->unique_crashes; +#ifdef _DEBUG + dump("DATA", buf, len); +#endif + if (unlikely(common_fuzz_stuff(afl, buf, len))) { return 1; } new_hit_cnt = afl->queued_paths + afl->unique_crashes; if (unlikely(new_hit_cnt != orig_hit_cnt)) { +#ifdef _DEBUG + fprintf(stderr, "NEW FIND\n"); +#endif *status = 1; } else { @@ -278,11 +470,33 @@ static int strntoull(const char *str, size_t sz, char **end, int base, } static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, - u64 pattern, u64 repl, u64 o_pattern, u32 idx, - u8 *orig_buf, u8 *buf, u32 len, u8 do_reverse, - u8 *status) { - - if (!buf) { FATAL("BUG: buf was NULL. Please report this.\n"); } + u64 pattern, u64 repl, u64 o_pattern, + u64 changed_val, u8 attr, u32 idx, u32 taint_len, + u8 *orig_buf, u8 *buf, u8 *cbuf, u32 len, + u8 do_reverse, u8 lvl, u8 *status) { + + // (void)(changed_val); // TODO + // we can use the information in changed_val to see if there is a + // computable i2s transformation. + // if (pattern != o_pattern && repl != changed_val) { + + // u64 in_diff = pattern - o_pattern, out_diff = repl - changed_val; + // if (in_diff != out_diff) { + + // switch(in_diff) { + + // detect uppercase <-> lowercase, base64, hex encoding, etc.: + // repl = reverse_transform(TYPE, pattern); + // } + // } + // } + // not 100% but would have a chance to be detected + + // fprintf(stderr, + // "Encode: %llx->%llx into %llx(<-%llx) at pos=%u " + // "taint_len=%u shape=%u attr=%u\n", + // o_pattern, pattern, repl, changed_val, idx, taint_len, + // h->shape + 1, attr); u64 *buf_64 = (u64 *)&buf[idx]; u32 *buf_32 = (u32 *)&buf[idx]; @@ -293,76 +507,215 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u16 *o_buf_16 = (u16 *)&orig_buf[idx]; u8 * o_buf_8 = &orig_buf[idx]; - u32 its_len = len - idx; - // *status = 0; + u32 its_len = MIN(len - idx, taint_len); u8 * endptr; u8 use_num = 0, use_unum = 0; unsigned long long unum; long long num; - if (afl->queue_cur->is_ascii) { + // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl == 3 + if (lvl & 4) { - endptr = buf_8; - if (strntoll(buf_8, len - idx, (char **)&endptr, 0, &num)) { + if (afl->queue_cur->is_ascii) { - if (!strntoull(buf_8, len - idx, (char **)&endptr, 0, &unum)) - use_unum = 1; + endptr = buf_8; + if (strntoll(buf_8, len - idx, (char **)&endptr, 0, &num)) { - } else + if (!strntoull(buf_8, len - idx, (char **)&endptr, 0, &unum)) + use_unum = 1; - use_num = 1; + } else - } + use_num = 1; - if (use_num && (u64)num == pattern) { + } - size_t old_len = endptr - buf_8; - size_t num_len = snprintf(NULL, 0, "%lld", num); +#ifdef _DEBUG + if (idx == 0) + fprintf(stderr, "ASCII is=%u use_num=%u use_unum=%u idx=%u %llx==%llx\n", + afl->queue_cur->is_ascii, use_num, use_unum, idx, num, pattern); +#endif - u8 *new_buf = afl_realloc((void **)&afl->out_scratch_buf, len + num_len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - memcpy(new_buf, buf, idx); + // num is likely not pattern as atoi("AAA") will be zero... + if (use_num && ((u64)num == pattern || !num)) { - snprintf(new_buf + idx, num_len, "%lld", num); - memcpy(new_buf + idx + num_len, buf_8 + old_len, len - idx - old_len); + u8 tmp_buf[32]; + size_t num_len = snprintf(tmp_buf, sizeof(tmp_buf), "%lld", repl); + size_t old_len = endptr - buf_8; - if (unlikely(its_fuzz(afl, new_buf, len, status))) { return 1; } + u8 *new_buf = afl_realloc((void **)&afl->out_scratch_buf, len + num_len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } - } else if (use_unum && unum == pattern) { + memcpy(new_buf, buf, idx); + memcpy(new_buf + idx, tmp_buf, num_len); + memcpy(new_buf + idx + num_len, buf_8 + old_len, len - idx - old_len); - size_t old_len = endptr - buf_8; - size_t num_len = snprintf(NULL, 0, "%llu", unum); + if (new_buf[idx + num_len] >= '0' && new_buf[idx + num_len] <= '9') { + + new_buf[idx + num_len] = ' '; + + } - u8 *new_buf = afl_realloc((void **)&afl->out_scratch_buf, len + num_len); - if (unlikely(!new_buf)) { PFATAL("alloc"); } - memcpy(new_buf, buf, idx); + if (unlikely(its_fuzz(afl, new_buf, len, status))) { return 1; } - snprintf(new_buf + idx, num_len, "%llu", unum); - memcpy(new_buf + idx + num_len, buf_8 + old_len, len - idx - old_len); + } else if (use_unum && (unum == pattern || !unum)) { - if (unlikely(its_fuzz(afl, new_buf, len, status))) { return 1; } + u8 tmp_buf[32]; + size_t num_len = snprintf(tmp_buf, sizeof(tmp_buf), "%llu", repl); + size_t old_len = endptr - buf_8; + + u8 *new_buf = afl_realloc((void **)&afl->out_scratch_buf, len + num_len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } + + memcpy(new_buf, buf, idx); + memcpy(new_buf + idx, tmp_buf, num_len); + memcpy(new_buf + idx + num_len, buf_8 + old_len, len - idx - old_len); + + if (new_buf[idx + num_len] >= '0' && new_buf[idx + num_len] <= '9') { + + new_buf[idx + num_len] = ' '; + + } + + if (unlikely(its_fuzz(afl, new_buf, len, status))) { return 1; } + + } } - if (SHAPE_BYTES(h->shape) >= 8 && *status != 1) { + // we only allow this for ascii2integer (above) + if (unlikely(pattern == o_pattern)) { return 0; } - if (its_len >= 8 && *buf_64 == pattern && *o_buf_64 == o_pattern) { + if ((lvl & 1) || ((lvl & 2) && (attr >= 8 && attr <= 15)) || attr >= 16) { - *buf_64 = repl; - if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } - *buf_64 = pattern; + if (SHAPE_BYTES(h->shape) >= 8 && *status != 1) { + + // if (its_len >= 8 && (attr == 0 || attr >= 8)) + // fprintf(stderr, + // "TestU64: %u>=4 %x==%llx" + // " %x==%llx (idx=%u attr=%u) <= %llx<-%llx\n", + // its_len, *buf_32, pattern, *o_buf_32, o_pattern, idx, attr, + // repl, changed_val); + + // if this is an fcmp (attr & 8 == 8) then do not compare the patterns - + // due to a bug in llvm dynamic float bitcasts do not work :( + // the value 16 means this is a +- 1.0 test case + if (its_len >= 8 && + ((*buf_64 == pattern && *o_buf_64 == o_pattern) || attr >= 16)) { + + u64 tmp_64 = *buf_64; + *buf_64 = repl; + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + if (*status == 1) { memcpy(cbuf + idx, buf_64, 8); } + *buf_64 = tmp_64; + + // fprintf(stderr, "Status=%u\n", *status); + + } + + // reverse encoding + if (do_reverse && *status != 1) { + + if (unlikely(cmp_extend_encoding(afl, h, SWAP64(pattern), SWAP64(repl), + SWAP64(o_pattern), SWAP64(changed_val), + attr, idx, taint_len, orig_buf, buf, + cbuf, len, 0, lvl, status))) { + + return 1; + + } + + } } - // reverse encoding - if (do_reverse && *status != 1) { + if (SHAPE_BYTES(h->shape) >= 4 && *status != 1) { - if (unlikely(cmp_extend_encoding(afl, h, SWAP64(pattern), SWAP64(repl), - SWAP64(o_pattern), idx, orig_buf, buf, - len, 0, status))) { + // if (its_len >= 4 && (attr <= 1 || attr >= 8)) + // fprintf(stderr, + // "TestU32: %u>=4 %x==%llx" + // " %x==%llx (idx=%u attr=%u) <= %llx<-%llx\n", + // its_len, *buf_32, pattern, *o_buf_32, o_pattern, idx, attr, + // repl, changed_val); - return 1; + if (its_len >= 4 && + ((*buf_32 == (u32)pattern && *o_buf_32 == (u32)o_pattern) || + attr >= 16)) { + + u32 tmp_32 = *buf_32; + *buf_32 = (u32)repl; + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + if (*status == 1) { memcpy(cbuf + idx, buf_32, 4); } + *buf_32 = tmp_32; + + // fprintf(stderr, "Status=%u\n", *status); + + } + + // reverse encoding + if (do_reverse && *status != 1) { + + if (unlikely(cmp_extend_encoding(afl, h, SWAP32(pattern), SWAP32(repl), + SWAP32(o_pattern), SWAP32(changed_val), + attr, idx, taint_len, orig_buf, buf, + cbuf, len, 0, lvl, status))) { + + return 1; + + } + + } + + } + + if (SHAPE_BYTES(h->shape) >= 2 && *status != 1) { + + if (its_len >= 2 && + ((*buf_16 == (u16)pattern && *o_buf_16 == (u16)o_pattern) || + attr >= 16)) { + + u16 tmp_16 = *buf_16; + *buf_16 = (u16)repl; + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + if (*status == 1) { memcpy(cbuf + idx, buf_16, 2); } + *buf_16 = tmp_16; + + } + + // reverse encoding + if (do_reverse && *status != 1) { + + if (unlikely(cmp_extend_encoding(afl, h, SWAP16(pattern), SWAP16(repl), + SWAP16(o_pattern), SWAP16(changed_val), + attr, idx, taint_len, orig_buf, buf, + cbuf, len, 0, lvl, status))) { + + return 1; + + } + + } + + } + + if (*status != 1) { // u8 + + // if (its_len >= 1 && (attr <= 1 || attr >= 8)) + // fprintf(stderr, + // "TestU8: %u>=1 %x==%x %x==%x (idx=%u attr=%u) <= %x<-%x\n", + // its_len, *buf_8, pattern, *o_buf_8, o_pattern, idx, attr, + // repl, changed_val); + + if (its_len >= 1 && + ((*buf_8 == (u8)pattern && *o_buf_8 == (u8)o_pattern) || + attr >= 16)) { + + u8 tmp_8 = *buf_8; + *buf_8 = (u8)repl; + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + if (*status == 1) { cbuf[idx] = *buf_8; } + *buf_8 = tmp_8; } @@ -370,49 +723,205 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - if (SHAPE_BYTES(h->shape) >= 4 && *status != 1) { + // here we add and subract 1 from the value, but only if it is not an + // == or != comparison + // Bits: 1 = Equal, 2 = Greater, 3 = Lesser, 4 = Float - if (its_len >= 4 && *buf_32 == (u32)pattern && - *o_buf_32 == (u32)o_pattern) { + if (lvl < 4) { return 0; } - *buf_32 = (u32)repl; - if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } - *buf_32 = pattern; + if (attr >= 8 && attr < 16) { // lesser/greater integer comparison + + u64 repl_new; + if (SHAPE_BYTES(h->shape) == 4 && its_len >= 4) { + + float *f = (float *)&repl; + float g = *f; + g += 1.0; + u32 *r = (u32 *)&g; + repl_new = (u32)*r; + + } else if (SHAPE_BYTES(h->shape) == 8 && its_len >= 8) { + + double *f = (double *)&repl; + double g = *f; + g += 1.0; + + u64 *r = (u64 *)&g; + repl_new = *r; + + } else { + + return 0; } - // reverse encoding - if (do_reverse && *status != 1) { + changed_val = repl_new; + + if (unlikely(cmp_extend_encoding(afl, h, pattern, repl_new, o_pattern, + changed_val, 16, idx, taint_len, orig_buf, + buf, cbuf, len, 1, lvl, status))) { + + return 1; + + } + + if (SHAPE_BYTES(h->shape) == 4) { + + float *f = (float *)&repl; + float g = *f; + g -= 1.0; + u32 *r = (u32 *)&g; + repl_new = (u32)*r; + + } else if (SHAPE_BYTES(h->shape) == 8) { + + double *f = (double *)&repl; + double g = *f; + g -= 1.0; + u64 *r = (u64 *)&g; + repl_new = *r; + + } else { + + return 0; + + } + + changed_val = repl_new; + + if (unlikely(cmp_extend_encoding(afl, h, pattern, repl_new, o_pattern, + changed_val, 16, idx, taint_len, orig_buf, + buf, cbuf, len, 1, lvl, status))) { + + return 1; + + } + + // transform double to float, llvm likes to do that internally ... + if (SHAPE_BYTES(h->shape) == 8 && its_len >= 4) { + + double *f = (double *)&repl; + float g = (float)*f; + repl_new = 0; +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + memcpy((char *)&repl_new, (char *)&g, 4); +#else + memcpy(((char *)&repl_new) + 4, (char *)&g, 4); +#endif + changed_val = repl_new; + h->shape = 3; // modify shape - if (unlikely(cmp_extend_encoding(afl, h, SWAP32(pattern), SWAP32(repl), - SWAP32(o_pattern), idx, orig_buf, buf, - len, 0, status))) { + // fprintf(stderr, "DOUBLE2FLOAT %llx\n", repl_new); + if (unlikely(cmp_extend_encoding( + afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx, + taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { + + h->shape = 7; return 1; } + h->shape = 7; // recover shape + + } + + } else if (attr > 1 && attr < 8) { // lesser/greater integer comparison + + u64 repl_new; + + repl_new = repl + 1; + changed_val = repl_new; + if (unlikely(cmp_extend_encoding(afl, h, pattern, repl_new, o_pattern, + changed_val, 32, idx, taint_len, orig_buf, + buf, cbuf, len, 1, lvl, status))) { + + return 1; + + } + + repl_new = repl - 1; + changed_val = repl_new; + if (unlikely(cmp_extend_encoding(afl, h, pattern, repl_new, o_pattern, + changed_val, 32, idx, taint_len, orig_buf, + buf, cbuf, len, 1, lvl, status))) { + + return 1; + } } - if (SHAPE_BYTES(h->shape) >= 2 && *status != 1) { + return 0; - if (its_len >= 2 && *buf_16 == (u16)pattern && - *o_buf_16 == (u16)o_pattern) { +} - *buf_16 = (u16)repl; +static u8 cmp_extend_encoding128(afl_state_t *afl, struct cmp_header *h, + u128 pattern, u128 repl, u128 o_pattern, + u128 changed_val, u8 attr, u32 idx, + u32 taint_len, u8 *orig_buf, u8 *buf, u8 *cbuf, + u32 len, u8 do_reverse, u8 lvl, u8 *status) { + + u128 *buf_128 = (u128 *)&buf[idx]; + u64 * buf0 = (u64 *)&buf[idx]; + u64 * buf1 = (u64 *)(buf + idx + 8); + u128 *o_buf_128 = (u128 *)&orig_buf[idx]; + u32 its_len = MIN(len - idx, taint_len); + u64 v10 = (u64)repl; + u64 v11 = (u64)(repl >> 64); + + // if this is an fcmp (attr & 8 == 8) then do not compare the patterns - + // due to a bug in llvm dynamic float bitcasts do not work :( + // the value 16 means this is a +- 1.0 test case + if (its_len >= 16) { + +#ifdef _DEBUG + fprintf(stderr, "TestU128: %u>=16 (idx=%u attr=%u) (%u)\n", its_len, idx, + attr, do_reverse); + u64 v00 = (u64)pattern; + u64 v01 = pattern >> 64; + u64 ov00 = (u64)o_pattern; + u64 ov01 = o_pattern >> 64; + u64 ov10 = (u64)changed_val; + u64 ov11 = changed_val >> 64; + u64 b00 = (u64)*buf_128; + u64 b01 = *buf_128 >> 64; + u64 ob00 = (u64)*o_buf_128; + u64 ob01 = *o_buf_128 >> 64; + fprintf(stderr, + "TestU128: %llx:%llx==%llx:%llx" + " %llx:%llx==%llx:%llx <= %llx:%llx<-%llx:%llx\n", + b01, b00, v01, v00, ob01, ob00, ov01, ov00, v11, v10, ov11, ov10); +#endif + + if (*buf_128 == pattern && *o_buf_128 == o_pattern) { + + u128 tmp_128 = *buf_128; + // *buf_128 = repl; <- this crashes +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + *buf0 = v10; + *buf1 = v11; +#else + *buf1 = v10; + *buf0 = v11; +#endif if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } - *buf_16 = (u16)pattern; + if (*status == 1) { memcpy(cbuf + idx, buf_128, 16); } + *buf_128 = tmp_128; + +#ifdef _DEBUG + fprintf(stderr, "Status=%u\n", *status); +#endif } // reverse encoding if (do_reverse && *status != 1) { - if (unlikely(cmp_extend_encoding(afl, h, SWAP16(pattern), SWAP16(repl), - SWAP16(o_pattern), idx, orig_buf, buf, - len, 0, status))) { + if (unlikely(cmp_extend_encoding128( + afl, h, SWAPN(pattern, 128), SWAPN(repl, 128), + SWAPN(o_pattern, 128), SWAPN(changed_val, 128), attr, idx, + taint_len, orig_buf, buf, cbuf, len, 0, lvl, status))) { return 1; @@ -422,14 +931,82 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - /* avoid CodeQL warning on unsigned overflow */ - if (/* SHAPE_BYTES(h->shape) >= 1 && */ *status != 1) { + return 0; - if (its_len >= 1 && *buf_8 == (u8)pattern && *o_buf_8 == (u8)o_pattern) { +} - *buf_8 = (u8)repl; +// uh a pointer read from (long double*) reads 12 bytes, not 10 ... +// so lets make this complicated. +static u8 cmp_extend_encoding_ld(afl_state_t *afl, struct cmp_header *h, + u8 *pattern, u8 *repl, u8 *o_pattern, + u8 *changed_val, u8 attr, u32 idx, + u32 taint_len, u8 *orig_buf, u8 *buf, u8 *cbuf, + u32 len, u8 do_reverse, u8 lvl, u8 *status) { + + u8 *buf_ld = &buf[idx], *o_buf_ld = &orig_buf[idx], backup[10]; + u32 its_len = MIN(len - idx, taint_len); + + if (its_len >= 10) { + +#ifdef _DEBUG + fprintf(stderr, "TestUld: %u>=10 (len=%u idx=%u attr=%u) (%u)\n", its_len, + len, idx, attr, do_reverse); + fprintf(stderr, "TestUld: "); + u32 i; + for (i = 0; i < 10; i++) + fprintf(stderr, "%02x", pattern[i]); + fprintf(stderr, "=="); + for (i = 0; i < 10; i++) + fprintf(stderr, "%02x", buf_ld[i]); + fprintf(stderr, " "); + for (i = 0; i < 10; i++) + fprintf(stderr, "%02x", o_pattern[i]); + fprintf(stderr, "=="); + for (i = 0; i < 10; i++) + fprintf(stderr, "%02x", o_buf_ld[i]); + fprintf(stderr, " <= "); + for (i = 0; i < 10; i++) + fprintf(stderr, "%02x", repl[i]); + fprintf(stderr, "=="); + for (i = 0; i < 10; i++) + fprintf(stderr, "%02x", changed_val[i]); + fprintf(stderr, "\n"); +#endif + + if (!memcmp(pattern, buf_ld, 10) && !memcmp(o_pattern, o_buf_ld, 10)) { + + // if this is an fcmp (attr & 8 == 8) then do not compare the patterns - + // due to a bug in llvm dynamic float bitcasts do not work :( + // the value 16 means this is a +- 1.0 test case + + memcpy(backup, buf_ld, 10); + memcpy(buf_ld, repl, 10); if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } - *buf_8 = (u8)pattern; + if (*status == 1) { memcpy(cbuf + idx, repl, 10); } + memcpy(buf_ld, backup, 10); + +#ifdef _DEBUG + fprintf(stderr, "Status=%u\n", *status); +#endif + + } + + } + + // reverse encoding + if (do_reverse && *status != 1) { + + u8 sp[10], sr[10], osp[10], osr[10]; + SWAPNN(sp, pattern, 10); + SWAPNN(sr, repl, 10); + SWAPNN(osp, o_pattern, 10); + SWAPNN(osr, changed_val, 10); + + if (unlikely(cmp_extend_encoding_ld(afl, h, sp, sr, osp, osr, attr, idx, + taint_len, orig_buf, buf, cbuf, len, 0, + lvl, status))) { + + return 1; } @@ -445,10 +1022,6 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { u32 k; u8 cons_ff = 0, cons_0 = 0; - - if (shape > sizeof(v)) - FATAL("shape is greater than %zu, please report!", sizeof(v)); - for (k = 0; k < shape; ++k) { if (b[k] == 0) { @@ -457,7 +1030,7 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { } else if (b[k] == 0xff) { - ++cons_ff; + ++cons_0; } else { @@ -493,28 +1066,126 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { } -static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { +static void try_to_add_to_dict128(afl_state_t *afl, u128 v) { - struct cmp_header *h = &afl->shm.cmp_map->headers[key]; - u32 i, j, idx; + u8 *b = (u8 *)&v; - u32 loggeds = h->hits; + u32 k; + u8 cons_ff = 0, cons_0 = 0; + for (k = 0; k < 16; ++k) { + + if (b[k] == 0) { + + ++cons_0; + + } else if (b[k] == 0xff) { + + ++cons_0; + + } else { + + cons_0 = cons_ff = 0; + + } + + // too many uninteresting values? try adding 2 64-bit values + if (cons_0 > 6 || cons_ff > 6) { + + u64 v64 = (u64)v; + try_to_add_to_dict(afl, v64, 8); + v64 = (u64)(v >> 64); + try_to_add_to_dict(afl, v64, 8); + + return; + + } + + } + + maybe_add_auto(afl, (u8 *)&v, 16); + u128 rev = SWAPN(v, 128); + maybe_add_auto(afl, (u8 *)&rev, 16); + +} + +static void try_to_add_to_dictN(afl_state_t *afl, u128 v, u8 size) { + + u8 *b = (u8 *)&v; + + u32 k; + u8 cons_ff = 0, cons_0 = 0; +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + for (k = 0; k < size; ++k) { + +#else + for (k = 16 - size; k < 16; ++k) { + +#endif + if (b[k] == 0) { + + ++cons_0; + + } else if (b[k] == 0xff) { + + ++cons_0; + + } else { + + cons_0 = cons_ff = 0; + + } + + } + + maybe_add_auto(afl, (u8 *)&v, size); + u128 rev = SWAPN(v, size); + maybe_add_auto(afl, (u8 *)&rev, size); + +} + +static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, + u32 len, u32 lvl, struct tainted *taint) { + + struct cmp_header *h = &afl->shm.cmp_map->headers[key]; + struct tainted * t; + u32 i, j, idx, taint_len; + u32 have_taint = 1, is_128 = 0, is_n = 0, is_ld = 0; + u32 loggeds = h->hits; if (h->hits > CMP_MAP_H) { loggeds = CMP_MAP_H; } u8 status = 0; - // opt not in the paper - u32 fails; - u8 found_one = 0; + u8 found_one = 0; /* loop cmps are useless, detect and ignore them */ - u64 s_v0, s_v1; - u8 s_v0_fixed = 1, s_v1_fixed = 1; - u8 s_v0_inc = 1, s_v1_inc = 1; - u8 s_v0_dec = 1, s_v1_dec = 1; + u128 s128_v0 = 0, s128_v1 = 0, orig_s128_v0 = 0, orig_s128_v1 = 0; + long double ld0, ld1, o_ld0, o_ld1; + u64 s_v0, s_v1; + u8 s_v0_fixed = 1, s_v1_fixed = 1; + u8 s_v0_inc = 1, s_v1_inc = 1; + u8 s_v0_dec = 1, s_v1_dec = 1; - for (i = 0; i < loggeds; ++i) { + switch (SHAPE_BYTES(h->shape)) { + + case 1: + case 2: + case 4: + case 8: + break; + case 16: + is_128 = 1; + break; + case 10: + if (h->attribute & 8) { is_ld = 1; } + // fall through + default: + is_n = 1; - fails = 0; + } + + // FCmp not in if level 1 only + if ((h->attribute & 8) && lvl < 2) return 0; + + for (i = 0; i < loggeds; ++i) { struct cmp_operands *o = &afl->shm.cmp_map->log[key][i]; @@ -551,55 +1222,242 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { } - for (idx = 0; idx < len && fails < 8; ++idx) { +#ifdef _DEBUG + fprintf(stderr, "Handling: %llx->%llx vs %llx->%llx attr=%u shape=%u\n", + orig_o->v0, o->v0, orig_o->v1, o->v1, h->attribute, + SHAPE_BYTES(h->shape)); +#endif + + if (taint) { + + t = taint; + + while (t->next) { + + t = t->next; + + } + + } else { + + have_taint = 0; + t = NULL; + + } + + if (unlikely(is_128 || is_n)) { + + s128_v0 = ((u128)o->v0) + (((u128)o->v0_128) << 64); + s128_v1 = ((u128)o->v1) + (((u128)o->v1_128) << 64); + orig_s128_v0 = ((u128)orig_o->v0) + (((u128)orig_o->v0_128) << 64); + orig_s128_v1 = ((u128)orig_o->v1) + (((u128)orig_o->v1_128) << 64); + + if (is_ld) { + +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + memcpy((char *)&ld0, (char *)&s128_v0, sizeof(long double)); + memcpy((char *)&ld1, (char *)&s128_v1, sizeof(long double)); + memcpy((char *)&o_ld0, (char *)&orig_s128_v0, sizeof(long double)); + memcpy((char *)&o_ld1, (char *)&orig_s128_v1, sizeof(long double)); +#else + memcpy((char *)&ld0, (char *)(&s128_v0) + 6, sizeof(long double)); + memcpy((char *)&ld1, (char *)(&s128_v1) + 6, sizeof(long double)); + memcpy((char *)&o_ld0, (char *)(&orig_s128_v0) + 6, + sizeof(long double)); + memcpy((char *)&o_ld1, (char *)(&orig_s128_v1) + 6, + sizeof(long double)); +#endif + + } + + } + + for (idx = 0; idx < len; ++idx) { + + if (have_taint) { + + if (!t || idx < t->pos) { + + continue; + + } else { + + taint_len = t->pos + t->len - idx; + + if (idx == t->pos + t->len - 1) { t = t->prev; } + + } + + } else { + + taint_len = len - idx; + + } status = 0; - if (unlikely(cmp_extend_encoding(afl, h, o->v0, o->v1, orig_o->v0, idx, - orig_buf, buf, len, 1, &status))) { - return 1; + if (is_ld) { // long double special case + + if (ld0 != o_ld0 && o_ld1 != o_ld0) { + + if (unlikely(cmp_extend_encoding_ld( + afl, h, (u8 *)&ld0, (u8 *)&ld1, (u8 *)&o_ld0, (u8 *)&o_ld1, + h->attribute, idx, taint_len, orig_buf, buf, cbuf, len, 1, + lvl, &status))) { + + return 1; + + } + + } + + if (status == 1) { + + found_one = 1; + break; + + } + + if (ld1 != o_ld1 && o_ld0 != o_ld1) { + + if (unlikely(cmp_extend_encoding_ld( + afl, h, (u8 *)&ld1, (u8 *)&ld0, (u8 *)&o_ld1, (u8 *)&o_ld0, + h->attribute, idx, taint_len, orig_buf, buf, cbuf, len, 1, + lvl, &status))) { + + return 1; + + } + + } + + if (status == 1) { + + found_one = 1; + break; + + } + + } + + if (is_128) { // u128 special case + + if (s128_v0 != orig_s128_v0 && orig_s128_v0 != orig_s128_v1) { + + if (unlikely(cmp_extend_encoding128( + afl, h, s128_v0, s128_v1, orig_s128_v0, orig_s128_v1, + h->attribute, idx, taint_len, orig_buf, buf, cbuf, len, 1, + lvl, &status))) { + + return 1; + + } + + } + + if (status == 1) { + + found_one = 1; + break; + + } + + if (s128_v1 != orig_s128_v1 && orig_s128_v1 != orig_s128_v0) { + + if (unlikely(cmp_extend_encoding128( + afl, h, s128_v1, s128_v0, orig_s128_v1, orig_s128_v0, + h->attribute, idx, taint_len, orig_buf, buf, cbuf, len, 1, + lvl, &status))) { + + return 1; + + } + + } + + if (status == 1) { + + found_one = 1; + break; + + } } - if (status == 2) { + // even for u128 and long double do cmp_extend_encoding() because + // if we got here their own special trials failed and it might just be + // a cast from e.g. u64 to u128 from the input data. - ++fails; + if ((o->v0 != orig_o->v0 || lvl >= 4) && orig_o->v0 != orig_o->v1) { - } else if (status == 1) { + if (unlikely(cmp_extend_encoding( + afl, h, o->v0, o->v1, orig_o->v0, orig_o->v1, h->attribute, idx, + taint_len, orig_buf, buf, cbuf, len, 1, lvl, &status))) { + return 1; + + } + + } + + if (status == 1) { + + found_one = 1; break; } status = 0; - if (unlikely(cmp_extend_encoding(afl, h, o->v1, o->v0, orig_o->v1, idx, - orig_buf, buf, len, 1, &status))) { + if ((o->v1 != orig_o->v1 || lvl >= 4) && orig_o->v0 != orig_o->v1) { - return 1; + if (unlikely(cmp_extend_encoding( + afl, h, o->v1, o->v0, orig_o->v1, orig_o->v0, h->attribute, idx, + taint_len, orig_buf, buf, cbuf, len, 1, lvl, &status))) { - } + return 1; - if (status == 2) { + } - ++fails; + } - } else if (status == 1) { + if (status == 1) { + found_one = 1; break; } } - if (status == 1) { found_one = 1; } +#ifdef _DEBUG + fprintf(stderr, + "END: %llx->%llx vs %llx->%llx attr=%u i=%u found=%u is128=%u " + "isN=%u size=%u\n", + orig_o->v0, o->v0, orig_o->v1, o->v1, h->attribute, i, found_one, + is_128, is_n, SHAPE_BYTES(h->shape)); +#endif // If failed, add to dictionary - if (fails == 8) { + if (!found_one) { if (afl->pass_stats[key].total == 0) { - try_to_add_to_dict(afl, o->v0, SHAPE_BYTES(h->shape)); - try_to_add_to_dict(afl, o->v1, SHAPE_BYTES(h->shape)); + if (unlikely(is_128)) { + + try_to_add_to_dict128(afl, s128_v0); + try_to_add_to_dict128(afl, s128_v1); + + } else if (unlikely(is_n)) { + + try_to_add_to_dictN(afl, s128_v0, SHAPE_BYTES(h->shape)); + try_to_add_to_dictN(afl, s128_v1, SHAPE_BYTES(h->shape)); + + } else { + + try_to_add_to_dict(afl, o->v0, SHAPE_BYTES(h->shape)); + try_to_add_to_dict(afl, o->v1, SHAPE_BYTES(h->shape)); + + } } @@ -630,20 +1488,19 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { } static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, - u8 *o_pattern, u32 idx, u8 *orig_buf, u8 *buf, - u32 len, u8 *status) { + u8 *o_pattern, u32 idx, u32 taint_len, + u8 *orig_buf, u8 *buf, u8 *cbuf, u32 len, + u8 *status) { u32 i; u32 its_len = MIN((u32)32, len - idx); - + its_len = MIN(its_len, taint_len); u8 save[32]; memcpy(save, &buf[idx], its_len); - *status = 0; - for (i = 0; i < its_len; ++i) { - if (pattern[i] != buf[idx + i] || o_pattern[i] != orig_buf[idx + i] || + if ((pattern[i] != buf[idx + i] && o_pattern[i] != orig_buf[idx + i]) || *status == 1) { break; @@ -654,6 +1511,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i); } + } memcpy(&buf[idx], save, i); @@ -661,23 +1520,21 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } -static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { +static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, + u32 len, struct tainted *taint) { + struct tainted * t; struct cmp_header *h = &afl->shm.cmp_map->headers[key]; - u32 i, j, idx; + u32 i, j, idx, have_taint = 1, taint_len; u32 loggeds = h->hits; if (h->hits > CMP_MAP_RTN_H) { loggeds = CMP_MAP_RTN_H; } u8 status = 0; - // opt not in the paper - // u32 fails = 0; u8 found_one = 0; for (i = 0; i < loggeds; ++i) { - u32 fails = 0; - struct cmpfn_operands *o = &((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[i]; @@ -696,50 +1553,84 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { } - for (idx = 0; idx < len && fails < 8; ++idx) { + if (taint) { - if (unlikely(rtn_extend_encoding(afl, o->v0, o->v1, orig_o->v0, idx, - orig_buf, buf, len, &status))) { + t = taint; + while (t->next) { - return 1; + t = t->next; } - if (status == 2) { + } else { - ++fails; + have_taint = 0; + t = NULL; - } else if (status == 1) { + } - break; + for (idx = 0; idx < len; ++idx) { + + if (have_taint) { + + if (!t || idx < t->pos) { + + continue; + + } else { + + taint_len = t->pos + t->len - idx; + + if (idx == t->pos + t->len - 1) { t = t->prev; } + + } + + } else { + + taint_len = len - idx; } - if (unlikely(rtn_extend_encoding(afl, o->v1, o->v0, orig_o->v1, idx, - orig_buf, buf, len, &status))) { + status = 0; + + if (unlikely(rtn_extend_encoding(afl, o->v0, o->v1, orig_o->v0, idx, + taint_len, orig_buf, buf, cbuf, len, + &status))) { return 1; } - if (status == 2) { + if (status == 1) { + + found_one = 1; + break; + + } + + status = 0; + + if (unlikely(rtn_extend_encoding(afl, o->v1, o->v0, orig_o->v1, idx, + taint_len, orig_buf, buf, cbuf, len, + &status))) { - ++fails; + return 1; - } else if (status == 1) { + } + if (status == 1) { + + found_one = 1; break; } } - if (status == 1) { found_one = 1; } - // If failed, add to dictionary - if (fails == 8) { + if (!found_one) { - if (afl->pass_stats[key].total == 0) { + if (unlikely(!afl->pass_stats[key].total)) { maybe_add_auto(afl, o->v0, SHAPE_BYTES(h->shape)); maybe_add_auto(afl, o->v1, SHAPE_BYTES(h->shape)); @@ -791,7 +1682,44 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, memcpy(afl->orig_cmp_map, afl->shm.cmp_map, sizeof(struct cmp_map)); - if (unlikely(colorization(afl, buf, len, exec_cksum))) { return 1; } + struct tainted *taint = NULL; + + if (!afl->queue_cur->taint || !afl->queue_cur->cmplog_colorinput) { + + if (unlikely(colorization(afl, buf, len, exec_cksum, &taint))) { return 1; } + + // no taint? still try, create a dummy to prevent again colorization + if (!taint) { + + taint = ck_alloc(sizeof(struct tainted)); + taint->len = len; + + } + + } else { + + buf = afl->queue_cur->cmplog_colorinput; + taint = afl->queue_cur->taint; + // reget the cmplog information + if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) { return 1; } + + } + +#ifdef _DEBUG + dump("ORIG", orig_buf, len); + dump("NEW ", buf, len); +#endif + + struct tainted *t = taint; + + while (t) { + +#ifdef _DEBUG + fprintf(stderr, "T: pos=%u len=%u\n", t->pos, t->len); +#endif + t = t->next; + + } // do it manually, forkserver clear only afl->fsrv.trace_bits memset(afl->shm.cmp_map->headers, 0, sizeof(afl->shm.cmp_map->headers)); @@ -807,15 +1735,38 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, afl->stage_max = 0; afl->stage_cur = 0; + u32 lvl; + u32 cmplog_done = afl->queue_cur->colorized; + u32 cmplog_lvl = afl->cmplog_lvl; + if (!cmplog_done) { + + lvl = 1; + + } else { + + lvl = 0; + + } + + if (cmplog_lvl >= 2 && cmplog_done < 2) { lvl += 2; } + if (cmplog_lvl >= 3 && cmplog_done < 3) { lvl += 4; } + + u8 *cbuf = afl_realloc((void **)&afl->in_scratch_buf, len + 128); + memcpy(cbuf, orig_buf, len); + u8 *virgin_backup = afl_realloc((void **)&afl->ex_buf, afl->shm.map_size); + memcpy(virgin_backup, afl->virgin_bits, afl->shm.map_size); + u32 k; for (k = 0; k < CMP_MAP_W; ++k) { if (!afl->shm.cmp_map->headers[k].hits) { continue; } - if (afl->pass_stats[k].total && - (rand_below(afl, afl->pass_stats[k].total) >= - afl->pass_stats[k].faileds || - afl->pass_stats[k].total == 0xff)) { + if (afl->pass_stats[k].faileds == 0xff || + afl->pass_stats[k].total == 0xff) { + +#ifdef _DEBUG + fprintf(stderr, "DISABLED %u\n", k); +#endif afl->shm.cmp_map->headers[k].hits = 0; // ignore this cmp @@ -841,11 +1792,19 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS) { - if (unlikely(cmp_fuzz(afl, k, orig_buf, buf, len))) { goto exit_its; } + if (unlikely(cmp_fuzz(afl, k, orig_buf, buf, cbuf, len, lvl, taint))) { + + goto exit_its; + + } } else { - if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, len))) { goto exit_its; } + if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, cbuf, len, taint))) { + + goto exit_its; + + } } @@ -854,12 +1813,86 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, r = 0; exit_its: + + afl->queue_cur->colorized = afl->cmplog_lvl; + if (afl->cmplog_lvl == CMPLOG_LVL_MAX) { + + ck_free(afl->queue_cur->cmplog_colorinput); + t = taint; + while (taint) { + + t = taint->next; + ck_free(taint); + taint = t; + + } + + afl->queue_cur->taint = NULL; + + } else { + + if (!afl->queue_cur->taint) { afl->queue_cur->taint = taint; } + + if (!afl->queue_cur->cmplog_colorinput) { + + afl->queue_cur->cmplog_colorinput = ck_alloc_nozero(len); + memcpy(afl->queue_cur->cmplog_colorinput, buf, len); + memcpy(buf, orig_buf, len); + + } + + } + + // copy the current virgin bits so we can recover the information + u8 *virgin_save = afl_realloc((void **)&afl->eff_buf, afl->shm.map_size); + memcpy(virgin_save, afl->virgin_bits, afl->shm.map_size); + // reset virgin bits to the backup previous to redqueen + memcpy(afl->virgin_bits, virgin_backup, afl->shm.map_size); + + u8 status = 0; + its_fuzz(afl, cbuf, len, &status); + + // now combine with the saved virgin bits +#ifdef WORD_SIZE_64 + u64 *v = (u64 *)afl->virgin_bits; + u64 *s = (u64 *)virgin_save; + u32 i; + for (i = 0; i < (afl->shm.map_size >> 3); i++) { + + v[i] &= s[i]; + + } + +#else + u32 *v = (u64 *)afl->virgin_bits; + u32 *s = (u64 *)virgin_save; + u32 i; + for (i = 0; i < (afl->shm.map_size >> 2); i++) { + + v[i] &= s[i]; + + } + +#endif + +#ifdef _DEBUG + dump("COMB", cbuf, len); + if (status == 1) { + + fprintf(stderr, "NEW COMBINED\n"); + + } else { + + fprintf(stderr, "NO new combined\n"); + + } + +#endif + new_hit_cnt = afl->queued_paths + afl->unique_crashes; afl->stage_finds[STAGE_ITS] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_ITS] += afl->fsrv.total_execs - orig_execs; - memcpy(buf, orig_buf, len); - return r; } diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 60c9684c..8423a3d1 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -102,6 +102,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->stats_update_freq = 1; afl->stats_avg_exec = 0; afl->skip_deterministic = 1; + afl->cmplog_lvl = 1; #ifndef NO_SPLICING afl->use_splicing = 1; #endif diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index bb2674f0..1e914ca6 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -77,13 +77,8 @@ static void at_exit() { } int kill_signal = SIGKILL; - /* AFL_KILL_SIGNAL should already be a valid int at this point */ - if (getenv("AFL_KILL_SIGNAL")) { - - kill_signal = atoi(getenv("AFL_KILL_SIGNAL")); - - } + if ((ptr = getenv("AFL_KILL_SIGNAL"))) { kill_signal = atoi(ptr); } if (pid1 > 0) { kill(pid1, kill_signal); } if (pid2 > 0) { kill(pid2, kill_signal); } @@ -103,13 +98,14 @@ static void usage(u8 *argv0, int more_help) { "Execution control settings:\n" " -p schedule - power schedules compute a seed's performance score:\n" - " -- see docs/power_schedules.md\n" + " fast(default), explore, exploit, seek, rare, mmopt, " + "coe, lin\n" + " quad -- see docs/power_schedules.md\n" " -f file - location read by the fuzzed program (default: stdin " "or @@)\n" " -t msec - timeout for each run (auto-scaled, 50-%u ms)\n" - " -m megs - memory limit for child process (%u MB, 0 = no limit)\n" + " -m megs - memory limit for child process (%u MB, 0 = no limit " + "[default])\n" " -Q - use binary-only instrumentation (QEMU mode)\n" " -U - use unicorn-based instrumentation (Unicorn mode)\n" " -W - use qemu-based instrumentation with Wine (Wine " @@ -125,7 +121,9 @@ static void usage(u8 *argv0, int more_help) { " See docs/README.MOpt.md\n" " -c program - enable CmpLog by specifying a binary compiled for " "it.\n" - " if using QEMU, just use -c 0.\n\n" + " if using QEMU, just use -c 0.\n" + " -l cmplog_level - set the complexity/intensivity of CmpLog.\n" + " Values: 1 (default), 2 (intensive) and 3 (heavy)\n\n" "Fuzzing behavior settings:\n" " -Z - sequential queue selection instead of weighted " @@ -337,7 +335,6 @@ int main(int argc, char **argv_orig, char **envp) { if (get_afl_env("AFL_DEBUG")) { debug = afl->debug = 1; } - // map_size = get_map_size(); afl_state_init(afl, map_size); afl->debug = debug; afl_fsrv_init(&afl->fsrv); @@ -358,7 +355,8 @@ int main(int argc, char **argv_orig, char **envp) { while ((opt = getopt( argc, argv, - "+b:c:i:I:o:f:F:m:t:T:dDnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:Z")) > 0) { + "+b:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNo:p:P:RQs:S:t:T:UV:Wx:Z")) > + 0) { switch (opt) { @@ -787,6 +785,26 @@ int main(int argc, char **argv_orig, char **envp) { } break; + case 'l': { + + afl->cmplog_lvl = atoi(optarg); + if (afl->cmplog_lvl < 1 || afl->cmplog_lvl > CMPLOG_LVL_MAX) { + + FATAL( + "Bad complog level value, accepted values are 1 (default), 2 and " + "%u.", + CMPLOG_LVL_MAX); + + } + + if (afl->cmplog_lvl == CMPLOG_LVL_MAX) { + + afl->cmplog_max_filesize = MAX_FILE; + + } + + } break; + case 'L': { /* MOpt mode */ if (afl->limit_time_sig) { FATAL("Multiple -L options not supported"); } @@ -1635,6 +1653,14 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->use_splicing) { ++afl->cycles_wo_finds; + + if (unlikely(afl->shm.cmplog_mode && + afl->cmplog_max_filesize < MAX_FILE)) { + + afl->cmplog_max_filesize <<= 4; + + } + switch (afl->expand_havoc) { case 0: @@ -1652,6 +1678,7 @@ int main(int argc, char **argv_orig, char **envp) { } afl->expand_havoc = 2; + if (afl->cmplog_lvl < 2) afl->cmplog_lvl = 2; break; case 2: // if (!have_p) afl->schedule = EXPLOIT; @@ -1665,11 +1692,14 @@ int main(int argc, char **argv_orig, char **envp) { afl->expand_havoc = 4; break; case 4: - // if not in sync mode, enable deterministic mode? - // if (!afl->sync_id) afl->skip_deterministic = 0; afl->expand_havoc = 5; + if (afl->cmplog_lvl < 3) afl->cmplog_lvl = 3; break; case 5: + // if not in sync mode, enable deterministic mode? + if (!afl->sync_id) afl->skip_deterministic = 0; + afl->expand_havoc = 6; + case 6: // nothing else currently break; -- cgit v1.2.3 From c71ce79963ffd3e1203d1078b8a60f91c4ecebf1 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 17 Jan 2021 15:18:20 +0100 Subject: fix colorization --- src/afl-fuzz-one.c | 6 ++---- src/afl-fuzz-redqueen.c | 56 ++++++++++++++++++++++++++++++------------------- src/afl-fuzz.c | 2 ++ src/afl-showmap.c | 25 ++++++++++++++++++---- 4 files changed, 59 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 596bae22..4ce22c08 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -562,8 +562,7 @@ u8 fuzz_one_original(afl_state_t *afl) { !(afl->fsrv.total_execs % afl->queued_paths) || get_cur_time() - afl->last_path_time > 15000) { - if (input_to_state_stage(afl, in_buf, out_buf, len, - afl->queue_cur->exec_cksum)) { + if (input_to_state_stage(afl, in_buf, out_buf, len)) { goto abandon_entry; @@ -2986,8 +2985,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { !(afl->fsrv.total_execs % afl->queued_paths) || get_cur_time() - afl->last_path_time > 15000) { - if (input_to_state_stage(afl, in_buf, out_buf, len, - afl->queue_cur->exec_cksum)) { + if (input_to_state_stage(afl, in_buf, out_buf, len)) { goto abandon_entry; diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 955a9232..052f59f1 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -88,7 +88,7 @@ static struct range *pop_biggest_range(struct range **ranges) { static void dump(char *txt, u8 *buf, u32 len) { u32 i; - fprintf(stderr, "DUMP %s %llx ", txt, hash64(buf, len, 0)); + fprintf(stderr, "DUMP %s %llx ", txt, hash64(buf, len, HASH_CONST)); for (i = 0; i < len; i++) fprintf(stderr, "%02x", buf[i]); fprintf(stderr, "\n"); @@ -117,6 +117,7 @@ static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u64 *cksum) { if (unlikely(common_fuzz_stuff(afl, buf, len))) { return 1; } *cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); + return 0; } @@ -200,7 +201,7 @@ static void type_replace(afl_state_t *afl, u8 *buf, u32 len) { } -static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum, +static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, struct tainted **taints) { struct range * ranges = add_range(NULL, 0, len - 1), *rng; @@ -208,18 +209,31 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum, u8 * backup = ck_alloc_nozero(len); u8 * changed = ck_alloc_nozero(len); - u64 orig_hit_cnt, new_hit_cnt; + u64 orig_hit_cnt, new_hit_cnt, exec_cksum; orig_hit_cnt = afl->queued_paths + afl->unique_crashes; afl->stage_name = "colorization"; afl->stage_short = "colorization"; afl->stage_max = (len << 1); - afl->stage_cur = 0; + + // in colorization we do not classify counts, hence we have to calculate + // the original checksum! + if (unlikely(get_exec_checksum(afl, buf, len, &exec_cksum))) { + + goto checksum_fail; + + } + memcpy(backup, buf, len); memcpy(changed, buf, len); type_replace(afl, changed, len); +#ifdef _DEBUG + dump("ORIG", buf, len); + dump("CHAN", changed, len); +#endif + while ((rng = pop_biggest_range(&ranges)) != NULL && afl->stage_cur < afl->stage_max) { @@ -227,7 +241,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum, memcpy(buf + rng->start, changed + rng->start, s); - u64 cksum; + u64 cksum = 0; u64 start_us = get_cur_time_us(); if (unlikely(get_exec_checksum(afl, buf, len, &cksum))) { @@ -633,11 +647,11 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, if (SHAPE_BYTES(h->shape) >= 4 && *status != 1) { // if (its_len >= 4 && (attr <= 1 || attr >= 8)) - // fprintf(stderr, - // "TestU32: %u>=4 %x==%llx" - // " %x==%llx (idx=%u attr=%u) <= %llx<-%llx\n", - // its_len, *buf_32, pattern, *o_buf_32, o_pattern, idx, attr, - // repl, changed_val); + // fprintf(stderr, + // "TestU32: %u>=4 %x==%llx" + // " %x==%llx (idx=%u attr=%u) <= %llx<-%llx\n", + // its_len, *buf_32, pattern, *o_buf_32, o_pattern, idx, attr, + // repl, changed_val); if (its_len >= 4 && ((*buf_32 == (u32)pattern && *o_buf_32 == (u32)o_pattern) || @@ -702,10 +716,10 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, if (*status != 1) { // u8 // if (its_len >= 1 && (attr <= 1 || attr >= 8)) - // fprintf(stderr, - // "TestU8: %u>=1 %x==%x %x==%x (idx=%u attr=%u) <= %x<-%x\n", - // its_len, *buf_8, pattern, *o_buf_8, o_pattern, idx, attr, - // repl, changed_val); + // fprintf(stderr, + // "TestU8: %u>=1 %x==%x %x==%x (idx=%u attr=%u) <= %x<-%x\n", + // its_len, *buf_8, (u8)pattern, *o_buf_8, (u8)o_pattern, idx, + // attr, (u8)repl, (u8)changed_val); if (its_len >= 1 && ((*buf_8 == (u8)pattern && *o_buf_8 == (u8)o_pattern) || @@ -1659,8 +1673,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, ///// Input to State stage // afl->queue_cur->exec_cksum -u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, - u64 exec_cksum) { +u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { u8 r = 1; if (unlikely(!afl->orig_cmp_map)) { @@ -1686,7 +1699,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, if (!afl->queue_cur->taint || !afl->queue_cur->cmplog_colorinput) { - if (unlikely(colorization(afl, buf, len, exec_cksum, &taint))) { return 1; } + if (unlikely(colorization(afl, buf, len, &taint))) { return 1; } // no taint? still try, create a dummy to prevent again colorization if (!taint) { @@ -1696,6 +1709,10 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, } +#ifdef _DEBUG + dump("NEW ", buf, len); +#endif + } else { buf = afl->queue_cur->cmplog_colorinput; @@ -1705,11 +1722,6 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len, } -#ifdef _DEBUG - dump("ORIG", orig_buf, len); - dump("NEW ", buf, len); -#endif - struct tainted *t = taint; while (t) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 1e914ca6..88c40ee8 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1094,6 +1094,8 @@ int main(int argc, char **argv_orig, char **envp) { } + if (afl->shm.cmplog_mode) { OKF("CmpLog level: %u", afl->cmplog_lvl); } + /* Dynamically allocate memory for AFLFast schedules */ if (afl->schedule >= FAST && afl->schedule <= RARE) { diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 5c9d38e0..5d98d646 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -42,6 +42,7 @@ #include "sharedmem.h" #include "forkserver.h" #include "common.h" +#include "hash.h" #include #include @@ -86,7 +87,8 @@ static u8 quiet_mode, /* Hide non-essential messages? */ binary_mode, /* Write output as a binary map */ keep_cores, /* Allow coredumps? */ remove_shm = 1, /* remove shmem? */ - collect_coverage; /* collect coverage */ + collect_coverage, /* collect coverage */ + no_classify; /* do not classify counts */ static volatile u8 stop_soon, /* Ctrl-C pressed? */ child_crashed; /* Child crashed? */ @@ -317,7 +319,9 @@ static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, u8 *mem, } - classify_counts(fsrv); + if (fsrv->trace_bits[0] == 1) { fsrv->trace_bits[0] = 0; } + + if (!no_classify) { classify_counts(fsrv); } if (!quiet_mode) { SAYF(cRST "-- Program output ends --\n"); } @@ -490,7 +494,9 @@ static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) { } - classify_counts(fsrv); + if (fsrv->trace_bits[0] == 1) { fsrv->trace_bits[0] = 0; } + + if (!no_classify) { classify_counts(fsrv); } if (!quiet_mode) { SAYF(cRST "-- Program output ends --\n"); } @@ -680,6 +686,7 @@ static void usage(u8 *argv0) { " -q - sink program's output and don't show messages\n" " -e - show edge coverage only, ignore hit counts\n" " -r - show real tuple values instead of AFL filter values\n" + " -s - do not classify the map\n" " -c - allow core dumps\n\n" "This tool displays raw tuple data captured by AFL instrumentation.\n" @@ -729,10 +736,14 @@ int main(int argc, char **argv_orig, char **envp) { if (getenv("AFL_QUIET") != NULL) { be_quiet = 1; } - while ((opt = getopt(argc, argv, "+i:o:f:m:t:A:eqCZQUWbcrh")) > 0) { + while ((opt = getopt(argc, argv, "+i:o:f:m:t:A:eqCZQUWbcrsh")) > 0) { switch (opt) { + case 's': + no_classify = 1; + break; + case 'C': collect_coverage = 1; quiet_mode = 1; @@ -1213,6 +1224,12 @@ int main(int argc, char **argv_orig, char **envp) { showmap_run_target(fsrv, use_argv); tcnt = write_results_to_file(fsrv, out_file); + if (!quiet_mode) { + + OKF("Hash of coverage map: %llx", + hash64(fsrv->trace_bits, fsrv->map_size, HASH_CONST)); + + } } -- cgit v1.2.3 From c8c0983ab84f4f7acf2dd52937a3cf5e41157a6b Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 17 Jan 2021 15:51:38 +0100 Subject: make combined test a define option --- src/afl-fuzz-redqueen.c | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 052f59f1..daa08f6a 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -29,6 +29,7 @@ #include "cmplog.h" //#define _DEBUG +//#define COMBINE ///// Colorization @@ -621,7 +622,9 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u64 tmp_64 = *buf_64; *buf_64 = repl; if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } +#ifdef COMBINE if (*status == 1) { memcpy(cbuf + idx, buf_64, 8); } +#endif *buf_64 = tmp_64; // fprintf(stderr, "Status=%u\n", *status); @@ -660,7 +663,9 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u32 tmp_32 = *buf_32; *buf_32 = (u32)repl; if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } +#ifdef COMBINE if (*status == 1) { memcpy(cbuf + idx, buf_32, 4); } +#endif *buf_32 = tmp_32; // fprintf(stderr, "Status=%u\n", *status); @@ -692,7 +697,9 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u16 tmp_16 = *buf_16; *buf_16 = (u16)repl; if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } +#ifdef COMBINE if (*status == 1) { memcpy(cbuf + idx, buf_16, 2); } +#endif *buf_16 = tmp_16; } @@ -728,7 +735,9 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u8 tmp_8 = *buf_8; *buf_8 = (u8)repl; if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } +#ifdef COMBINE if (*status == 1) { cbuf[idx] = *buf_8; } +#endif *buf_8 = tmp_8; } @@ -920,7 +929,9 @@ static u8 cmp_extend_encoding128(afl_state_t *afl, struct cmp_header *h, *buf0 = v11; #endif if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } +#ifdef COMBINE if (*status == 1) { memcpy(cbuf + idx, buf_128, 16); } +#endif *buf_128 = tmp_128; #ifdef _DEBUG @@ -996,7 +1007,9 @@ static u8 cmp_extend_encoding_ld(afl_state_t *afl, struct cmp_header *h, memcpy(backup, buf_ld, 10); memcpy(buf_ld, repl, 10); if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } +#ifdef COMBINE if (*status == 1) { memcpy(cbuf + idx, repl, 10); } +#endif memcpy(buf_ld, backup, 10); #ifdef _DEBUG @@ -1506,6 +1519,10 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, u8 *orig_buf, u8 *buf, u8 *cbuf, u32 len, u8 *status) { +#ifndef COMBINE + (void)(cbuf); +#endif + u32 i; u32 its_len = MIN((u32)32, len - idx); its_len = MIN(its_len, taint_len); @@ -1525,7 +1542,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } +#ifdef COMBINE if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i); } +#endif } @@ -1763,10 +1782,14 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { if (cmplog_lvl >= 2 && cmplog_done < 2) { lvl += 2; } if (cmplog_lvl >= 3 && cmplog_done < 3) { lvl += 4; } +#ifdef COMBINE u8 *cbuf = afl_realloc((void **)&afl->in_scratch_buf, len + 128); memcpy(cbuf, orig_buf, len); u8 *virgin_backup = afl_realloc((void **)&afl->ex_buf, afl->shm.map_size); memcpy(virgin_backup, afl->virgin_bits, afl->shm.map_size); +#else + u8 *cbuf = NULL; +#endif u32 k; for (k = 0; k < CMP_MAP_W; ++k) { @@ -1855,6 +1878,7 @@ exit_its: } +#ifdef COMBINE // copy the current virgin bits so we can recover the information u8 *virgin_save = afl_realloc((void **)&afl->eff_buf, afl->shm.map_size); memcpy(virgin_save, afl->virgin_bits, afl->shm.map_size); @@ -1865,7 +1889,7 @@ exit_its: its_fuzz(afl, cbuf, len, &status); // now combine with the saved virgin bits -#ifdef WORD_SIZE_64 + #ifdef WORD_SIZE_64 u64 *v = (u64 *)afl->virgin_bits; u64 *s = (u64 *)virgin_save; u32 i; @@ -1875,19 +1899,19 @@ exit_its: } -#else + #else u32 *v = (u64 *)afl->virgin_bits; u32 *s = (u64 *)virgin_save; - u32 i; + u32 i; for (i = 0; i < (afl->shm.map_size >> 2); i++) { v[i] &= s[i]; } -#endif + #endif -#ifdef _DEBUG + #ifdef _DEBUG dump("COMB", cbuf, len); if (status == 1) { @@ -1899,6 +1923,7 @@ exit_its: } + #endif #endif new_hit_cnt = afl->queued_paths + afl->unique_crashes; @@ -1909,3 +1934,7 @@ exit_its: } +#ifdef COMBINE + #undef COMBINE +#endif + -- cgit v1.2.3 From 6b375489ed5dced4d0f55c334382f418a12e825a Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 17 Jan 2021 16:50:10 +0100 Subject: better extint cmplog --- src/afl-fuzz-redqueen.c | 148 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 140 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index daa08f6a..28d34ea6 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -28,7 +28,7 @@ #include "afl-fuzz.h" #include "cmplog.h" -//#define _DEBUG +#define _DEBUG //#define COMBINE ///// Colorization @@ -233,6 +233,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, #ifdef _DEBUG dump("ORIG", buf, len); dump("CHAN", changed, len); + fprintf(stderr, "CKSUM %llx (%u)\n", exec_cksum, afl->fsrv.map_size); #endif while ((rng = pop_biggest_range(&ranges)) != NULL && @@ -722,11 +723,11 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, if (*status != 1) { // u8 - // if (its_len >= 1 && (attr <= 1 || attr >= 8)) - // fprintf(stderr, - // "TestU8: %u>=1 %x==%x %x==%x (idx=%u attr=%u) <= %x<-%x\n", - // its_len, *buf_8, (u8)pattern, *o_buf_8, (u8)o_pattern, idx, - // attr, (u8)repl, (u8)changed_val); + if (its_len >= 1 && (attr <= 1 || attr >= 8)) + fprintf(stderr, + "TestU8: %u>=1 %x==%x %x==%x (idx=%u attr=%u) <= %x<-%x\n", + its_len, *buf_8, (u8)pattern, *o_buf_8, (u8)o_pattern, idx, + attr, (u8)repl, (u8)changed_val); if (its_len >= 1 && ((*buf_8 == (u8)pattern && *o_buf_8 == (u8)o_pattern) || @@ -960,6 +961,93 @@ static u8 cmp_extend_encoding128(afl_state_t *afl, struct cmp_header *h, } +static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, + u128 pattern, u128 repl, u128 o_pattern, + u128 changed_val, u8 attr, u32 idx, + u32 taint_len, u8 *orig_buf, u8 *buf, u8 *cbuf, + u32 len, u8 do_reverse, u8 lvl, u8 *status) { + + u8 *ptr = (u8 *)&buf[idx]; + u8 *o_ptr = (u8 *)&orig_buf[idx]; + u32 its_len = MIN(len - idx, taint_len); + u32 shape = h->shape + 1; + u8 *p = (u8 *)&pattern; + u8 *o_p = (u8 *)&o_pattern; + u8 *r = (u8 *)&repl; + u8 *o_r = (u8 *)&changed_val; + u8 backup[16]; +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + size_t off = 0; +#else + size_t off = 16 - shape; +#endif + + if (its_len >= shape) { + +#ifdef _DEBUG + fprintf(stderr, "TestUN: %u>=%u (len=%u idx=%u attr=%u) (%u) ", its_len, + shape, len, idx, attr, do_reverse); + u32 i; + for (i = 0; i < shape; i++) + fprintf(stderr, "%02x", ptr[0]); + fprintf(stderr, "=="); + for (i = 0; i < shape; i++) + fprintf(stderr, "%02x", p[off + 0]); + fprintf(stderr, " "); + for (i = 0; i < shape; i++) + fprintf(stderr, "%02x", o_ptr[0]); + fprintf(stderr, "=="); + for (i = 0; i < shape; i++) + fprintf(stderr, "%02x", o_p[off + 0]); + fprintf(stderr, " <= "); + for (i = 0; i < shape; i++) + fprintf(stderr, "%02x", r[off + 0]); + fprintf(stderr, " ("); + for (i = 0; i < shape; i++) + fprintf(stderr, "%02x", o_r[off + 0]); + fprintf(stderr, ")\n"); +#endif + + if (!memcmp(ptr, p + off, shape) && !memcmp(o_ptr, o_p + off, shape)) { + + memcpy(backup, ptr, shape); + memcpy(ptr, r + off, shape); + + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + +#ifdef COMBINE + if (*status == 1) { memcpy(cbuf + idx, r, shape); } +#endif + + memcpy(ptr, backup, shape); + +#ifdef _DEBUG + fprintf(stderr, "Status=%u\n", *status); +#endif + + } + + // reverse encoding + if (do_reverse && *status != 1) { + + if (unlikely(cmp_extend_encoding128( + afl, h, SWAPN(pattern, (shape << 3)), SWAPN(repl, (shape << 3)), + SWAPN(o_pattern, (shape << 3)), SWAPN(changed_val, (shape << 3)), + attr, idx, taint_len, orig_buf, buf, cbuf, len, 0, lvl, + status))) { + + return 1; + + } + + } + + } + + return 0; + +} + // uh a pointer read from (long double*) reads 12 bytes, not 10 ... // so lets make this complicated. static u8 cmp_extend_encoding_ld(afl_state_t *afl, struct cmp_header *h, @@ -1365,9 +1453,53 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } - } + } else + + if (is_n) { // _ExtInt special case + + if (s128_v0 != orig_s128_v0 && orig_s128_v0 != orig_s128_v1) { + + if (unlikely(cmp_extend_encodingN( + afl, h, s128_v0, s128_v1, orig_s128_v0, orig_s128_v1, + h->attribute, idx, taint_len, orig_buf, buf, cbuf, len, 1, + lvl, &status))) { + + return 1; + + } + + } + + if (status == 1) { + + found_one = 1; + break; + + } + + if (s128_v1 != orig_s128_v1 && orig_s128_v1 != orig_s128_v0) { + + if (unlikely(cmp_extend_encodingN( + afl, h, s128_v1, s128_v0, orig_s128_v1, orig_s128_v0, + h->attribute, idx, taint_len, orig_buf, buf, cbuf, len, 1, + lvl, &status))) { + + return 1; + + } + + } + + if (status == 1) { + + found_one = 1; + break; + + } + + } else - if (is_128) { // u128 special case + if (is_128) { // u128 special case if (s128_v0 != orig_s128_v0 && orig_s128_v0 != orig_s128_v1) { -- cgit v1.2.3 From 8951f906230ee9b7b2c27d92281d9da81302c694 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 17 Jan 2021 17:03:08 +0100 Subject: no cmplog when no taint is found --- src/afl-fuzz-redqueen.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 28d34ea6..2cc578bb 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -1855,8 +1855,11 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { // no taint? still try, create a dummy to prevent again colorization if (!taint) { - taint = ck_alloc(sizeof(struct tainted)); - taint->len = len; +#ifdef _DEBUG + fprintf(stderr, "TAINT FAILED\n"); +#endif + afl->queue_cur->colorized = CMPLOG_LVL_MAX; + return 0; } -- cgit v1.2.3 From 7b97410060f52b33f0c9894bb202690c453c4bcb Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 17 Jan 2021 23:47:04 +0100 Subject: cmplog introspection --- src/afl-fuzz-redqueen.c | 80 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 2cc578bb..56246d6e 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -29,7 +29,8 @@ #include "cmplog.h" #define _DEBUG -//#define COMBINE +#define COMBINE +#define CMPLOG_INTROSPECTION ///// Colorization @@ -210,6 +211,10 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u8 * backup = ck_alloc_nozero(len); u8 * changed = ck_alloc_nozero(len); +#if defined(_DEBUG) || defined(CMPLOG_INTROSPECTION) + u64 start_time = get_cur_time(); +#endif + u64 orig_hit_cnt, new_hit_cnt, exec_cksum; orig_hit_cnt = afl->queued_paths + afl->unique_crashes; @@ -368,26 +373,30 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, new_hit_cnt = afl->queued_paths + afl->unique_crashes; -#ifdef _DEBUG - /* +#if defined(_DEBUG) || defined(CMPLOG_INTROSPECTION) + FILE *f = stderr; + if (afl->not_on_tty) { + char fn[4096]; snprintf(fn, sizeof(fn), "%s/introspection_color.txt", afl->out_dir); - FILE *f = fopen(fn, "a"); - if (f) { + f = fopen(fn, "a"); - */ - FILE *f = stderr; - fprintf(f, - "Colorization: fname=%s len=%u result=%u execs=%u found=%llu " - "taint=%u\n", - afl->queue_cur->fname, len, afl->queue_cur->colorized, afl->stage_cur, - new_hit_cnt - orig_hit_cnt, positions); -/* - fclose(f); + } + + if (f) { + + fprintf( + f, + "Colorization: fname=%s len=%u ms=%llu result=%u execs=%u found=%llu " + "taint=%u\n", + afl->queue_cur->fname, len, get_cur_time() - start_time, + afl->queue_cur->colorized, afl->stage_cur, new_hit_cnt - orig_hit_cnt, + positions); + + if (afl->not_on_tty) { fclose(f); } } -*/ #endif afl->stage_finds[STAGE_COLORIZATION] += new_hit_cnt - orig_hit_cnt; @@ -1863,6 +1872,15 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } +#ifdef _DEBUG + else if (taint->pos == 0 && taint->len == len) { + + fprintf(stderr, "TAINT FULL\n"); + + } + +#endif + #ifdef _DEBUG dump("NEW ", buf, len); #endif @@ -1887,6 +1905,11 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } +#if defined(_DEBUG) || defined(CMPLOG_INTROSPECTION) + u64 start_time = get_cur_time(); + u32 cmp_locations = 0; +#endif + // do it manually, forkserver clear only afl->fsrv.trace_bits memset(afl->shm.cmp_map->headers, 0, sizeof(afl->shm.cmp_map->headers)); @@ -1960,6 +1983,10 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { if (!afl->shm.cmp_map->headers[k].hits) { continue; } +#if defined(_DEBUG) || defined(CMPLOG_INTROSPECTION) + ++cmp_locations; +#endif + if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS) { if (unlikely(cmp_fuzz(afl, k, orig_buf, buf, cbuf, len, lvl, taint))) { @@ -2065,6 +2092,29 @@ exit_its: afl->stage_finds[STAGE_ITS] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_ITS] += afl->fsrv.total_execs - orig_execs; +#if defined(_DEBUG) || defined(CMPLOG_INTROSPECTION) + FILE *f = stderr; + if (afl->not_on_tty) { + + char fn[4096]; + snprintf(fn, sizeof(fn), "%s/introspection_color.txt", afl->out_dir); + f = fopen(fn, "a"); + + } + + if (f) { + + fprintf(f, + "Cmplog: fname=%s len=%u ms=%llu result=%u finds=%llu entries=%u\n", + afl->queue_cur->fname, len, get_cur_time() - start_time, r, + new_hit_cnt - orig_hit_cnt, cmp_locations); + + if (afl->not_on_tty) { fclose(f); } + + } + +#endif + return r; } -- cgit v1.2.3 From a8b06291630d5e4b71ab1eb2fee856c1c576bf4b Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 18 Jan 2021 09:26:16 +0100 Subject: introspection, favor extint over long double --- src/afl-cc.c | 3 +- src/afl-fuzz-redqueen.c | 202 +++++++++--------------------------------------- 2 files changed, 38 insertions(+), 167 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 02c9c7c5..d44f069a 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -683,6 +683,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (!strncmp(cur, "--afl", 5)) continue; if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue; if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue; + if (!strncmp(cur, "-fno-unroll", 11)) continue; if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined")) continue; @@ -703,7 +704,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (!strcmp(cur, "-shared")) shared_linking = 1; if (!strncmp(cur, "-O", 2)) have_o = 1; - if (!strncmp(cur, "-f", 2) && strstr(cur, "unroll-loop")) have_unroll = 1; + if (!strncmp(cur, "-funroll-loop", 13)) have_unroll = 1; cc_params[cc_par_cnt++] = cur; diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 56246d6e..3cfe05bc 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -31,6 +31,7 @@ #define _DEBUG #define COMBINE #define CMPLOG_INTROSPECTION +#define ARITHMETIC_LESSER_GREATER ///// Colorization @@ -375,6 +376,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, #if defined(_DEBUG) || defined(CMPLOG_INTROSPECTION) FILE *f = stderr; + #ifndef _DEBUG if (afl->not_on_tty) { char fn[4096]; @@ -383,6 +385,8 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, } + #endif + if (f) { fprintf( @@ -393,7 +397,9 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, afl->queue_cur->colorized, afl->stage_cur, new_hit_cnt - orig_hit_cnt, positions); + #ifndef _DEBUG if (afl->not_on_tty) { fclose(f); } + #endif } @@ -758,11 +764,15 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // here we add and subract 1 from the value, but only if it is not an // == or != comparison - // Bits: 1 = Equal, 2 = Greater, 3 = Lesser, 4 = Float + // Bits: 1 = Equal, 2 = Greater, 4 = Lesser, 8 = Float + // 16 = modified float, 32 = modified integer (modified = wont match + // in original buffer) +#ifdef ARITHMETIC_LESSER_GREATER if (lvl < 4) { return 0; } - if (attr >= 8 && attr < 16) { // lesser/greater integer comparison + // lesser/greater FP comparison + if (!(attr & 1) && (attr & 6) && (attr >= 8 && attr < 16)) { u64 repl_new; if (SHAPE_BYTES(h->shape) == 4 && its_len >= 4) { @@ -836,11 +846,11 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, double *f = (double *)&repl; float g = (float)*f; repl_new = 0; -#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) memcpy((char *)&repl_new, (char *)&g, 4); -#else + #else memcpy(((char *)&repl_new) + 4, (char *)&g, 4); -#endif + #endif changed_val = repl_new; h->shape = 3; // modify shape @@ -850,7 +860,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx, taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { - h->shape = 7; + h->shape = 7; // recover shape return 1; } @@ -859,7 +869,9 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - } else if (attr > 1 && attr < 8) { // lesser/greater integer comparison + } else if (!(attr & 1) && (attr & 6) && attr < 8) { + + // lesser/greater integer comparison u64 repl_new; @@ -885,6 +897,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } +#endif /* ARITHMETIC_LESSER_GREATER */ + return 0; } @@ -1057,89 +1071,6 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, } -// uh a pointer read from (long double*) reads 12 bytes, not 10 ... -// so lets make this complicated. -static u8 cmp_extend_encoding_ld(afl_state_t *afl, struct cmp_header *h, - u8 *pattern, u8 *repl, u8 *o_pattern, - u8 *changed_val, u8 attr, u32 idx, - u32 taint_len, u8 *orig_buf, u8 *buf, u8 *cbuf, - u32 len, u8 do_reverse, u8 lvl, u8 *status) { - - u8 *buf_ld = &buf[idx], *o_buf_ld = &orig_buf[idx], backup[10]; - u32 its_len = MIN(len - idx, taint_len); - - if (its_len >= 10) { - -#ifdef _DEBUG - fprintf(stderr, "TestUld: %u>=10 (len=%u idx=%u attr=%u) (%u)\n", its_len, - len, idx, attr, do_reverse); - fprintf(stderr, "TestUld: "); - u32 i; - for (i = 0; i < 10; i++) - fprintf(stderr, "%02x", pattern[i]); - fprintf(stderr, "=="); - for (i = 0; i < 10; i++) - fprintf(stderr, "%02x", buf_ld[i]); - fprintf(stderr, " "); - for (i = 0; i < 10; i++) - fprintf(stderr, "%02x", o_pattern[i]); - fprintf(stderr, "=="); - for (i = 0; i < 10; i++) - fprintf(stderr, "%02x", o_buf_ld[i]); - fprintf(stderr, " <= "); - for (i = 0; i < 10; i++) - fprintf(stderr, "%02x", repl[i]); - fprintf(stderr, "=="); - for (i = 0; i < 10; i++) - fprintf(stderr, "%02x", changed_val[i]); - fprintf(stderr, "\n"); -#endif - - if (!memcmp(pattern, buf_ld, 10) && !memcmp(o_pattern, o_buf_ld, 10)) { - - // if this is an fcmp (attr & 8 == 8) then do not compare the patterns - - // due to a bug in llvm dynamic float bitcasts do not work :( - // the value 16 means this is a +- 1.0 test case - - memcpy(backup, buf_ld, 10); - memcpy(buf_ld, repl, 10); - if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } -#ifdef COMBINE - if (*status == 1) { memcpy(cbuf + idx, repl, 10); } -#endif - memcpy(buf_ld, backup, 10); - -#ifdef _DEBUG - fprintf(stderr, "Status=%u\n", *status); -#endif - - } - - } - - // reverse encoding - if (do_reverse && *status != 1) { - - u8 sp[10], sr[10], osp[10], osr[10]; - SWAPNN(sp, pattern, 10); - SWAPNN(sr, repl, 10); - SWAPNN(osp, o_pattern, 10); - SWAPNN(osr, changed_val, 10); - - if (unlikely(cmp_extend_encoding_ld(afl, h, sp, sr, osp, osr, attr, idx, - taint_len, orig_buf, buf, cbuf, len, 0, - lvl, status))) { - - return 1; - - } - - } - - return 0; - -} - static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { u8 *b = (u8 *)&v; @@ -1273,7 +1204,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, struct cmp_header *h = &afl->shm.cmp_map->headers[key]; struct tainted * t; u32 i, j, idx, taint_len; - u32 have_taint = 1, is_128 = 0, is_n = 0, is_ld = 0; + u32 have_taint = 1, is_128 = 0, is_n = 0; u32 loggeds = h->hits; if (h->hits > CMP_MAP_H) { loggeds = CMP_MAP_H; } @@ -1281,12 +1212,11 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, u8 found_one = 0; /* loop cmps are useless, detect and ignore them */ - u128 s128_v0 = 0, s128_v1 = 0, orig_s128_v0 = 0, orig_s128_v1 = 0; - long double ld0, ld1, o_ld0, o_ld1; - u64 s_v0, s_v1; - u8 s_v0_fixed = 1, s_v1_fixed = 1; - u8 s_v0_inc = 1, s_v1_inc = 1; - u8 s_v0_dec = 1, s_v1_dec = 1; + u128 s128_v0 = 0, s128_v1 = 0, orig_s128_v0 = 0, orig_s128_v1 = 0; + u64 s_v0, s_v1; + u8 s_v0_fixed = 1, s_v1_fixed = 1; + u8 s_v0_inc = 1, s_v1_inc = 1; + u8 s_v0_dec = 1, s_v1_dec = 1; switch (SHAPE_BYTES(h->shape)) { @@ -1298,9 +1228,6 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, case 16: is_128 = 1; break; - case 10: - if (h->attribute & 8) { is_ld = 1; } - // fall through default: is_n = 1; @@ -1376,24 +1303,6 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, orig_s128_v0 = ((u128)orig_o->v0) + (((u128)orig_o->v0_128) << 64); orig_s128_v1 = ((u128)orig_o->v1) + (((u128)orig_o->v1_128) << 64); - if (is_ld) { - -#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) - memcpy((char *)&ld0, (char *)&s128_v0, sizeof(long double)); - memcpy((char *)&ld1, (char *)&s128_v1, sizeof(long double)); - memcpy((char *)&o_ld0, (char *)&orig_s128_v0, sizeof(long double)); - memcpy((char *)&o_ld1, (char *)&orig_s128_v1, sizeof(long double)); -#else - memcpy((char *)&ld0, (char *)(&s128_v0) + 6, sizeof(long double)); - memcpy((char *)&ld1, (char *)(&s128_v1) + 6, sizeof(long double)); - memcpy((char *)&o_ld0, (char *)(&orig_s128_v0) + 6, - sizeof(long double)); - memcpy((char *)&o_ld1, (char *)(&orig_s128_v1) + 6, - sizeof(long double)); -#endif - - } - } for (idx = 0; idx < len; ++idx) { @@ -1420,51 +1329,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, status = 0; - if (is_ld) { // long double special case - - if (ld0 != o_ld0 && o_ld1 != o_ld0) { - - if (unlikely(cmp_extend_encoding_ld( - afl, h, (u8 *)&ld0, (u8 *)&ld1, (u8 *)&o_ld0, (u8 *)&o_ld1, - h->attribute, idx, taint_len, orig_buf, buf, cbuf, len, 1, - lvl, &status))) { - - return 1; - - } - - } - - if (status == 1) { - - found_one = 1; - break; - - } - - if (ld1 != o_ld1 && o_ld0 != o_ld1) { - - if (unlikely(cmp_extend_encoding_ld( - afl, h, (u8 *)&ld1, (u8 *)&ld0, (u8 *)&o_ld1, (u8 *)&o_ld0, - h->attribute, idx, taint_len, orig_buf, buf, cbuf, len, 1, - lvl, &status))) { - - return 1; - - } - - } - - if (status == 1) { - - found_one = 1; - break; - - } - - } else - - if (is_n) { // _ExtInt special case + if (is_n) { // _ExtInt special case if (s128_v0 != orig_s128_v0 && orig_s128_v0 != orig_s128_v1) { @@ -1552,7 +1417,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } - // even for u128 and long double do cmp_extend_encoding() because + // even for u128 and _ExtInt we do cmp_extend_encoding() because // if we got here their own special trials failed and it might just be // a cast from e.g. u64 to u128 from the input data. @@ -1995,7 +1860,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } - } else { + } else if (lvl & 1) { if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, cbuf, len, taint))) { @@ -2064,7 +1929,7 @@ exit_its: #else u32 *v = (u64 *)afl->virgin_bits; u32 *s = (u64 *)virgin_save; - u32 i; + u32 i; for (i = 0; i < (afl->shm.map_size >> 2); i++) { v[i] &= s[i]; @@ -2094,6 +1959,7 @@ exit_its: #if defined(_DEBUG) || defined(CMPLOG_INTROSPECTION) FILE *f = stderr; + #ifndef _DEBUG if (afl->not_on_tty) { char fn[4096]; @@ -2102,6 +1968,8 @@ exit_its: } + #endif + if (f) { fprintf(f, @@ -2109,7 +1977,9 @@ exit_its: afl->queue_cur->fname, len, get_cur_time() - start_time, r, new_hit_cnt - orig_hit_cnt, cmp_locations); + #ifndef _DEBUG if (afl->not_on_tty) { fclose(f); } + #endif } -- cgit v1.2.3 From bbfaa6092db55dc49f771a97ad7da7985c343531 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 18 Jan 2021 11:12:20 +0100 Subject: refactoring --- src/afl-fuzz-redqueen.c | 294 +++++++++--------------------------------------- 1 file changed, 51 insertions(+), 243 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 3cfe05bc..94667254 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -28,10 +28,10 @@ #include "afl-fuzz.h" #include "cmplog.h" -#define _DEBUG -#define COMBINE +//#define _DEBUG +//#define COMBINE #define CMPLOG_INTROSPECTION -#define ARITHMETIC_LESSER_GREATER +//#define ARITHMETIC_LESSER_GREATER ///// Colorization @@ -524,7 +524,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // not 100% but would have a chance to be detected // fprintf(stderr, - // "Encode: %llx->%llx into %llx(<-%llx) at pos=%u " + // "Encode: %llx->%llx into %llx(<-%llx) at idx=%u " // "taint_len=%u shape=%u attr=%u\n", // o_pattern, pattern, repl, changed_val, idx, taint_len, // h->shape + 1, attr); @@ -622,12 +622,12 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, if (SHAPE_BYTES(h->shape) >= 8 && *status != 1) { - // if (its_len >= 8 && (attr == 0 || attr >= 8)) - // fprintf(stderr, - // "TestU64: %u>=4 %x==%llx" - // " %x==%llx (idx=%u attr=%u) <= %llx<-%llx\n", - // its_len, *buf_32, pattern, *o_buf_32, o_pattern, idx, attr, - // repl, changed_val); + // if (its_len >= 8) + // fprintf(stderr, + // "TestU64: %u>=8 (idx=%u attr=%u) %llx==%llx" + // " %llx==%llx <= %llx<-%llx\n", + // its_len, idx, attr, *buf_64, pattern, *o_buf_64, o_pattern, + // repl, changed_val); // if this is an fcmp (attr & 8 == 8) then do not compare the patterns - // due to a bug in llvm dynamic float bitcasts do not work :( @@ -667,10 +667,10 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // if (its_len >= 4 && (attr <= 1 || attr >= 8)) // fprintf(stderr, - // "TestU32: %u>=4 %x==%llx" - // " %x==%llx (idx=%u attr=%u) <= %llx<-%llx\n", - // its_len, *buf_32, pattern, *o_buf_32, o_pattern, idx, attr, - // repl, changed_val); + // "TestU32: %u>=4 (idx=%u attr=%u) %x==%x" + // " %x==%x <= %x<-%x\n", + // its_len, idx, attr, *buf_32, (u32)pattern, *o_buf_32, + // (u32)o_pattern, (u32)repl, (u32)changed_val); if (its_len >= 4 && ((*buf_32 == (u32)pattern && *o_buf_32 == (u32)o_pattern) || @@ -738,11 +738,11 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, if (*status != 1) { // u8 - if (its_len >= 1 && (attr <= 1 || attr >= 8)) - fprintf(stderr, - "TestU8: %u>=1 %x==%x %x==%x (idx=%u attr=%u) <= %x<-%x\n", - its_len, *buf_8, (u8)pattern, *o_buf_8, (u8)o_pattern, idx, - attr, (u8)repl, (u8)changed_val); + // if (its_len >= 1 && (attr <= 1 || attr >= 8)) + // fprintf(stderr, + // "TestU8: %u>=1 (idx=%u attr=%u) %x==%x %x==%x <= %x<-%x\n", + // its_len, idx, attr, *buf_8, (u8)pattern, *o_buf_8, + // (u8)o_pattern, (u8)repl, (u8)changed_val); if (its_len >= 1 && ((*buf_8 == (u8)pattern && *o_buf_8 == (u8)o_pattern) || @@ -903,87 +903,6 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } -static u8 cmp_extend_encoding128(afl_state_t *afl, struct cmp_header *h, - u128 pattern, u128 repl, u128 o_pattern, - u128 changed_val, u8 attr, u32 idx, - u32 taint_len, u8 *orig_buf, u8 *buf, u8 *cbuf, - u32 len, u8 do_reverse, u8 lvl, u8 *status) { - - u128 *buf_128 = (u128 *)&buf[idx]; - u64 * buf0 = (u64 *)&buf[idx]; - u64 * buf1 = (u64 *)(buf + idx + 8); - u128 *o_buf_128 = (u128 *)&orig_buf[idx]; - u32 its_len = MIN(len - idx, taint_len); - u64 v10 = (u64)repl; - u64 v11 = (u64)(repl >> 64); - - // if this is an fcmp (attr & 8 == 8) then do not compare the patterns - - // due to a bug in llvm dynamic float bitcasts do not work :( - // the value 16 means this is a +- 1.0 test case - if (its_len >= 16) { - -#ifdef _DEBUG - fprintf(stderr, "TestU128: %u>=16 (idx=%u attr=%u) (%u)\n", its_len, idx, - attr, do_reverse); - u64 v00 = (u64)pattern; - u64 v01 = pattern >> 64; - u64 ov00 = (u64)o_pattern; - u64 ov01 = o_pattern >> 64; - u64 ov10 = (u64)changed_val; - u64 ov11 = changed_val >> 64; - u64 b00 = (u64)*buf_128; - u64 b01 = *buf_128 >> 64; - u64 ob00 = (u64)*o_buf_128; - u64 ob01 = *o_buf_128 >> 64; - fprintf(stderr, - "TestU128: %llx:%llx==%llx:%llx" - " %llx:%llx==%llx:%llx <= %llx:%llx<-%llx:%llx\n", - b01, b00, v01, v00, ob01, ob00, ov01, ov00, v11, v10, ov11, ov10); -#endif - - if (*buf_128 == pattern && *o_buf_128 == o_pattern) { - - u128 tmp_128 = *buf_128; - // *buf_128 = repl; <- this crashes -#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) - *buf0 = v10; - *buf1 = v11; -#else - *buf1 = v10; - *buf0 = v11; -#endif - if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } -#ifdef COMBINE - if (*status == 1) { memcpy(cbuf + idx, buf_128, 16); } -#endif - *buf_128 = tmp_128; - -#ifdef _DEBUG - fprintf(stderr, "Status=%u\n", *status); -#endif - - } - - // reverse encoding - if (do_reverse && *status != 1) { - - if (unlikely(cmp_extend_encoding128( - afl, h, SWAPN(pattern, 128), SWAPN(repl, 128), - SWAPN(o_pattern, 128), SWAPN(changed_val, 128), attr, idx, - taint_len, orig_buf, buf, cbuf, len, 0, lvl, status))) { - - return 1; - - } - - } - - } - - return 0; - -} - static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, u128 pattern, u128 repl, u128 o_pattern, u128 changed_val, u8 attr, u32 idx, @@ -992,13 +911,12 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, u8 *ptr = (u8 *)&buf[idx]; u8 *o_ptr = (u8 *)&orig_buf[idx]; - u32 its_len = MIN(len - idx, taint_len); - u32 shape = h->shape + 1; u8 *p = (u8 *)&pattern; u8 *o_p = (u8 *)&o_pattern; u8 *r = (u8 *)&repl; - u8 *o_r = (u8 *)&changed_val; u8 backup[16]; + u32 its_len = MIN(len - idx, taint_len); + u32 shape = h->shape + 1; #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) size_t off = 0; #else @@ -1008,27 +926,28 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, if (its_len >= shape) { #ifdef _DEBUG - fprintf(stderr, "TestUN: %u>=%u (len=%u idx=%u attr=%u) (%u) ", its_len, - shape, len, idx, attr, do_reverse); + // fprintf(stderr, "TestUN: %u>=%u (len=%u idx=%u attr=%u off=%lu) (%u) ", + // its_len, shape, len, idx, attr, off, do_reverse); u32 i; + u8 *o_r = (u8 *)&changed_val; for (i = 0; i < shape; i++) - fprintf(stderr, "%02x", ptr[0]); + fprintf(stderr, "%02x", ptr[i]); fprintf(stderr, "=="); for (i = 0; i < shape; i++) - fprintf(stderr, "%02x", p[off + 0]); + fprintf(stderr, "%02x", p[off + i]); fprintf(stderr, " "); for (i = 0; i < shape; i++) - fprintf(stderr, "%02x", o_ptr[0]); + fprintf(stderr, "%02x", o_ptr[i]); fprintf(stderr, "=="); for (i = 0; i < shape; i++) - fprintf(stderr, "%02x", o_p[off + 0]); + fprintf(stderr, "%02x", o_p[off + i]); fprintf(stderr, " <= "); for (i = 0; i < shape; i++) - fprintf(stderr, "%02x", r[off + 0]); - fprintf(stderr, " ("); + fprintf(stderr, "%02x", r[off + i]); + fprintf(stderr, "<-"); for (i = 0; i < shape; i++) - fprintf(stderr, "%02x", o_r[off + 0]); - fprintf(stderr, ")\n"); + fprintf(stderr, "%02x", o_r[off + i]); + fprintf(stderr, "\n"); #endif if (!memcmp(ptr, p + off, shape) && !memcmp(o_ptr, o_p + off, shape)) { @@ -1053,7 +972,7 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, // reverse encoding if (do_reverse && *status != 1) { - if (unlikely(cmp_extend_encoding128( + if (unlikely(cmp_extend_encodingN( afl, h, SWAPN(pattern, (shape << 3)), SWAPN(repl, (shape << 3)), SWAPN(o_pattern, (shape << 3)), SWAPN(changed_val, (shape << 3)), attr, idx, taint_len, orig_buf, buf, cbuf, len, 0, lvl, @@ -1121,48 +1040,6 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { } -static void try_to_add_to_dict128(afl_state_t *afl, u128 v) { - - u8 *b = (u8 *)&v; - - u32 k; - u8 cons_ff = 0, cons_0 = 0; - for (k = 0; k < 16; ++k) { - - if (b[k] == 0) { - - ++cons_0; - - } else if (b[k] == 0xff) { - - ++cons_0; - - } else { - - cons_0 = cons_ff = 0; - - } - - // too many uninteresting values? try adding 2 64-bit values - if (cons_0 > 6 || cons_ff > 6) { - - u64 v64 = (u64)v; - try_to_add_to_dict(afl, v64, 8); - v64 = (u64)(v >> 64); - try_to_add_to_dict(afl, v64, 8); - - return; - - } - - } - - maybe_add_auto(afl, (u8 *)&v, 16); - u128 rev = SWAPN(v, 128); - maybe_add_auto(afl, (u8 *)&rev, 16); - -} - static void try_to_add_to_dictN(afl_state_t *afl, u128 v, u8 size) { u8 *b = (u8 *)&v; @@ -1170,9 +1047,11 @@ static void try_to_add_to_dictN(afl_state_t *afl, u128 v, u8 size) { u32 k; u8 cons_ff = 0, cons_0 = 0; #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + u32 off = 0; for (k = 0; k < size; ++k) { #else + u32 off = 16 - size; for (k = 16 - size; k < 16; ++k) { #endif @@ -1192,9 +1071,9 @@ static void try_to_add_to_dictN(afl_state_t *afl, u128 v, u8 size) { } - maybe_add_auto(afl, (u8 *)&v, size); + maybe_add_auto(afl, (u8 *)&v + off, size); u128 rev = SWAPN(v, size); - maybe_add_auto(afl, (u8 *)&rev, size); + maybe_add_auto(afl, (u8 *)&rev + off, size); } @@ -1204,7 +1083,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, struct cmp_header *h = &afl->shm.cmp_map->headers[key]; struct tainted * t; u32 i, j, idx, taint_len; - u32 have_taint = 1, is_128 = 0, is_n = 0; + u32 have_taint = 1, is_n = 0; u32 loggeds = h->hits; if (h->hits > CMP_MAP_H) { loggeds = CMP_MAP_H; } @@ -1225,15 +1104,12 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, case 4: case 8: break; - case 16: - is_128 = 1; - break; default: is_n = 1; } - // FCmp not in if level 1 only + // FP handling only from lvl 2 onwards if ((h->attribute & 8) && lvl < 2) return 0; for (i = 0; i < loggeds; ++i) { @@ -1279,24 +1155,14 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, SHAPE_BYTES(h->shape)); #endif - if (taint) { - - t = taint; - - while (t->next) { - - t = t->next; - - } - - } else { + t = taint; + while (t->next) { - have_taint = 0; - t = NULL; + t = t->next; } - if (unlikely(is_128 || is_n)) { + if (unlikely(is_n)) { s128_v0 = ((u128)o->v0) + (((u128)o->v0_128) << 64); s128_v1 = ((u128)o->v1) + (((u128)o->v1_128) << 64); @@ -1329,7 +1195,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, status = 0; - if (is_n) { // _ExtInt special case + if (is_n) { // _ExtInt special case including u128 if (s128_v0 != orig_s128_v0 && orig_s128_v0 != orig_s128_v1) { @@ -1371,50 +1237,6 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } - } else - - if (is_128) { // u128 special case - - if (s128_v0 != orig_s128_v0 && orig_s128_v0 != orig_s128_v1) { - - if (unlikely(cmp_extend_encoding128( - afl, h, s128_v0, s128_v1, orig_s128_v0, orig_s128_v1, - h->attribute, idx, taint_len, orig_buf, buf, cbuf, len, 1, - lvl, &status))) { - - return 1; - - } - - } - - if (status == 1) { - - found_one = 1; - break; - - } - - if (s128_v1 != orig_s128_v1 && orig_s128_v1 != orig_s128_v0) { - - if (unlikely(cmp_extend_encoding128( - afl, h, s128_v1, s128_v0, orig_s128_v1, orig_s128_v0, - h->attribute, idx, taint_len, orig_buf, buf, cbuf, len, 1, - lvl, &status))) { - - return 1; - - } - - } - - if (status == 1) { - - found_one = 1; - break; - - } - } // even for u128 and _ExtInt we do cmp_extend_encoding() because @@ -1464,10 +1286,10 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, #ifdef _DEBUG fprintf(stderr, - "END: %llx->%llx vs %llx->%llx attr=%u i=%u found=%u is128=%u " + "END: %llx->%llx vs %llx->%llx attr=%u i=%u found=%u " "isN=%u size=%u\n", orig_o->v0, o->v0, orig_o->v1, o->v1, h->attribute, i, found_one, - is_128, is_n, SHAPE_BYTES(h->shape)); + is_n, SHAPE_BYTES(h->shape)); #endif // If failed, add to dictionary @@ -1475,12 +1297,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, if (afl->pass_stats[key].total == 0) { - if (unlikely(is_128)) { - - try_to_add_to_dict128(afl, s128_v0); - try_to_add_to_dict128(afl, s128_v1); - - } else if (unlikely(is_n)) { + if (unlikely(is_n)) { try_to_add_to_dictN(afl, s128_v0, SHAPE_BYTES(h->shape)); try_to_add_to_dictN(afl, s128_v1, SHAPE_BYTES(h->shape)); @@ -1592,19 +1409,10 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } - if (taint) { - - t = taint; - while (t->next) { - - t = t->next; - - } - - } else { + t = taint; + while (t->next) { - have_taint = 0; - t = NULL; + t = t->next; } @@ -1764,7 +1572,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { while (t) { #ifdef _DEBUG - fprintf(stderr, "T: pos=%u len=%u\n", t->pos, t->len); + fprintf(stderr, "T: idx=%u len=%u\n", t->pos, t->len); #endif t = t->next; -- cgit v1.2.3 From 0c061186cf873011ca2636a307c9d6dc85ca6880 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 18 Jan 2021 12:13:36 +0100 Subject: less logging --- src/afl-fuzz-redqueen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 94667254..0c12657d 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -380,7 +380,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, if (afl->not_on_tty) { char fn[4096]; - snprintf(fn, sizeof(fn), "%s/introspection_color.txt", afl->out_dir); + snprintf(fn, sizeof(fn), "%s/introspection_cmplog.txt", afl->out_dir); f = fopen(fn, "a"); } @@ -1771,7 +1771,7 @@ exit_its: if (afl->not_on_tty) { char fn[4096]; - snprintf(fn, sizeof(fn), "%s/introspection_color.txt", afl->out_dir); + snprintf(fn, sizeof(fn), "%s/introspection_cmplog.txt", afl->out_dir); f = fopen(fn, "a"); } -- cgit v1.2.3 From 94a15b8ca790a87d88c7513282250257f32a48c0 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 18 Jan 2021 13:20:40 +0100 Subject: arithmetic also for <= >= --- src/afl-fuzz-redqueen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 0c12657d..fe98f031 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -772,7 +772,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, if (lvl < 4) { return 0; } // lesser/greater FP comparison - if (!(attr & 1) && (attr & 6) && (attr >= 8 && attr < 16)) { + if ((attr & 6) && (attr >= 8 && attr < 16)) { u64 repl_new; if (SHAPE_BYTES(h->shape) == 4 && its_len >= 4) { @@ -869,7 +869,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - } else if (!(attr & 1) && (attr & 6) && attr < 8) { + } else if ((attr & 6) && attr < 8) { // lesser/greater integer comparison -- cgit v1.2.3 From 0b545aaeb45141e91273f2358ec457293c341c92 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 18 Jan 2021 20:18:18 +0100 Subject: use enums, support cmplog map collisions --- src/afl-fuzz-redqueen.c | 129 ++++++++++++++++++++++++++++++------------------ 1 file changed, 80 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index fe98f031..56022fa6 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -33,7 +33,26 @@ #define CMPLOG_INTROSPECTION //#define ARITHMETIC_LESSER_GREATER -///// Colorization +// CMP attribute enum +enum { + + IS_EQUAL = 1, + IS_GREATER = 2, + IS_LESSER = 4, + IS_FP = 8, + IS_FP_MOD = 16, + IS_INT_MOD = 32 + +}; + +// CMPLOG LVL +enum { + + LVL1 = 1, + LVL2 = 2, + LVL3 = 4 + +}; struct range { @@ -545,8 +564,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, unsigned long long unum; long long num; - // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl == 3 - if (lvl & 4) { + // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3 + if (lvl & LVL3) { if (afl->queue_cur->is_ascii) { @@ -618,7 +637,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // we only allow this for ascii2integer (above) if (unlikely(pattern == o_pattern)) { return 0; } - if ((lvl & 1) || ((lvl & 2) && (attr >= 8 && attr <= 15)) || attr >= 16) { + if ((lvl & LVL1) || ((lvl & LVL2) && (attr >= IS_FP && attr < IS_FP_MOD)) || + attr >= IS_FP_MOD) { if (SHAPE_BYTES(h->shape) >= 8 && *status != 1) { @@ -632,8 +652,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // if this is an fcmp (attr & 8 == 8) then do not compare the patterns - // due to a bug in llvm dynamic float bitcasts do not work :( // the value 16 means this is a +- 1.0 test case - if (its_len >= 8 && - ((*buf_64 == pattern && *o_buf_64 == o_pattern) || attr >= 16)) { + if (its_len >= 8 && ((*buf_64 == pattern && *o_buf_64 == o_pattern) || + attr >= IS_FP_MOD)) { u64 tmp_64 = *buf_64; *buf_64 = repl; @@ -674,7 +694,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, if (its_len >= 4 && ((*buf_32 == (u32)pattern && *o_buf_32 == (u32)o_pattern) || - attr >= 16)) { + attr >= IS_FP_MOD)) { u32 tmp_32 = *buf_32; *buf_32 = (u32)repl; @@ -708,7 +728,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, if (its_len >= 2 && ((*buf_16 == (u16)pattern && *o_buf_16 == (u16)o_pattern) || - attr >= 16)) { + attr >= IS_FP_MOD)) { u16 tmp_16 = *buf_16; *buf_16 = (u16)repl; @@ -738,7 +758,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, if (*status != 1) { // u8 - // if (its_len >= 1 && (attr <= 1 || attr >= 8)) + // if (its_len >= 1) // fprintf(stderr, // "TestU8: %u>=1 (idx=%u attr=%u) %x==%x %x==%x <= %x<-%x\n", // its_len, idx, attr, *buf_8, (u8)pattern, *o_buf_8, @@ -746,7 +766,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, if (its_len >= 1 && ((*buf_8 == (u8)pattern && *o_buf_8 == (u8)o_pattern) || - attr >= 16)) { + attr >= IS_FP_MOD)) { u8 tmp_8 = *buf_8; *buf_8 = (u8)repl; @@ -769,10 +789,11 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // in original buffer) #ifdef ARITHMETIC_LESSER_GREATER - if (lvl < 4) { return 0; } + if (lvl < LVL3) { return 0; } // lesser/greater FP comparison - if ((attr & 6) && (attr >= 8 && attr < 16)) { + if ((attr & (IS_LESSER + IS_GREATER)) && + (attr >= IS_FP && attr < IS_FP_MOD)) { u64 repl_new; if (SHAPE_BYTES(h->shape) == 4 && its_len >= 4) { @@ -869,7 +890,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - } else if ((attr & 6) && attr < 8) { + } else if ((attr & (IS_LESSER + IS_GREATER)) && attr < IS_FP) { // lesser/greater integer comparison @@ -903,6 +924,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } +#ifdef WORD_SIZE_64 + static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, u128 pattern, u128 repl, u128 o_pattern, u128 changed_val, u8 attr, u32 idx, @@ -917,15 +940,15 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, u8 backup[16]; u32 its_len = MIN(len - idx, taint_len); u32 shape = h->shape + 1; -#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) size_t off = 0; -#else + #else size_t off = 16 - shape; -#endif + #endif if (its_len >= shape) { -#ifdef _DEBUG + #ifdef _DEBUG // fprintf(stderr, "TestUN: %u>=%u (len=%u idx=%u attr=%u off=%lu) (%u) ", // its_len, shape, len, idx, attr, off, do_reverse); u32 i; @@ -948,7 +971,7 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, for (i = 0; i < shape; i++) fprintf(stderr, "%02x", o_r[off + i]); fprintf(stderr, "\n"); -#endif + #endif if (!memcmp(ptr, p + off, shape) && !memcmp(o_ptr, o_p + off, shape)) { @@ -957,15 +980,15 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } -#ifdef COMBINE + #ifdef COMBINE if (*status == 1) { memcpy(cbuf + idx, r, shape); } -#endif + #endif memcpy(ptr, backup, shape); -#ifdef _DEBUG + #ifdef _DEBUG fprintf(stderr, "Status=%u\n", *status); -#endif + #endif } @@ -990,6 +1013,8 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, } +#endif + static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { u8 *b = (u8 *)&v; @@ -1040,21 +1065,22 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { } +#ifdef WORD_SIZE_64 static void try_to_add_to_dictN(afl_state_t *afl, u128 v, u8 size) { u8 *b = (u8 *)&v; u32 k; u8 cons_ff = 0, cons_0 = 0; -#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) u32 off = 0; for (k = 0; k < size; ++k) { -#else - u32 off = 16 - size; + #else + u32 off = 16 - size; for (k = 16 - size; k < 16; ++k) { -#endif + #endif if (b[k] == 0) { ++cons_0; @@ -1077,6 +1103,8 @@ static void try_to_add_to_dictN(afl_state_t *afl, u128 v, u8 size) { } +#endif + static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, u32 len, u32 lvl, struct tainted *taint) { @@ -1091,11 +1119,13 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, u8 found_one = 0; /* loop cmps are useless, detect and ignore them */ +#ifdef WORD_SIZE_64 u128 s128_v0 = 0, s128_v1 = 0, orig_s128_v0 = 0, orig_s128_v1 = 0; - u64 s_v0, s_v1; - u8 s_v0_fixed = 1, s_v1_fixed = 1; - u8 s_v0_inc = 1, s_v1_inc = 1; - u8 s_v0_dec = 1, s_v1_dec = 1; +#endif + u64 s_v0, s_v1; + u8 s_v0_fixed = 1, s_v1_fixed = 1; + u8 s_v0_inc = 1, s_v1_inc = 1; + u8 s_v0_dec = 1, s_v1_dec = 1; switch (SHAPE_BYTES(h->shape)) { @@ -1110,7 +1140,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } // FP handling only from lvl 2 onwards - if ((h->attribute & 8) && lvl < 2) return 0; + if ((h->attribute & IS_FP) && lvl < LVL2) return 0; for (i = 0; i < loggeds; ++i) { @@ -1162,6 +1192,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } +#ifdef WORD_SIZE_64 if (unlikely(is_n)) { s128_v0 = ((u128)o->v0) + (((u128)o->v0_128) << 64); @@ -1171,6 +1202,8 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } +#endif + for (idx = 0; idx < len; ++idx) { if (have_taint) { @@ -1195,6 +1228,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, status = 0; +#ifdef WORD_SIZE_64 if (is_n) { // _ExtInt special case including u128 if (s128_v0 != orig_s128_v0 && orig_s128_v0 != orig_s128_v1) { @@ -1239,11 +1273,13 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } +#endif + // even for u128 and _ExtInt we do cmp_extend_encoding() because // if we got here their own special trials failed and it might just be // a cast from e.g. u64 to u128 from the input data. - if ((o->v0 != orig_o->v0 || lvl >= 4) && orig_o->v0 != orig_o->v1) { + if ((o->v0 != orig_o->v0 || lvl >= LVL3) && orig_o->v0 != orig_o->v1) { if (unlikely(cmp_extend_encoding( afl, h, o->v0, o->v1, orig_o->v0, orig_o->v1, h->attribute, idx, @@ -1263,7 +1299,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } status = 0; - if ((o->v1 != orig_o->v1 || lvl >= 4) && orig_o->v0 != orig_o->v1) { + if ((o->v1 != orig_o->v1 || lvl >= LVL3) && orig_o->v0 != orig_o->v1) { if (unlikely(cmp_extend_encoding( afl, h, o->v1, o->v0, orig_o->v1, orig_o->v0, h->attribute, idx, @@ -1521,13 +1557,6 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } - // do it manually, forkserver clear only afl->fsrv.trace_bits - memset(afl->shm.cmp_map->headers, 0, sizeof(afl->shm.cmp_map->headers)); - - if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) { return 1; } - - memcpy(afl->orig_cmp_map, afl->shm.cmp_map, sizeof(struct cmp_map)); - struct tainted *taint = NULL; if (!afl->queue_cur->taint || !afl->queue_cur->cmplog_colorinput) { @@ -1562,8 +1591,6 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { buf = afl->queue_cur->cmplog_colorinput; taint = afl->queue_cur->taint; - // reget the cmplog information - if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) { return 1; } } @@ -1583,9 +1610,13 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { u32 cmp_locations = 0; #endif - // do it manually, forkserver clear only afl->fsrv.trace_bits - memset(afl->shm.cmp_map->headers, 0, sizeof(afl->shm.cmp_map->headers)); - + // Generate the cmplog data + // manually clear the full cmp_map + memset(afl->shm.cmp_map, 0, sizeof(struct cmp_map)); + if (unlikely(common_fuzz_cmplog_stuff(afl, orig_buf, len))) { return 1; } + memcpy(afl->orig_cmp_map, afl->shm.cmp_map, sizeof(struct cmp_map)); + // manually clear just the headers + memset(afl->shm.cmp_map->headers, 0, sizeof(struct cmp_header)); if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) { return 1; } u64 orig_hit_cnt, new_hit_cnt; @@ -1602,7 +1633,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { u32 cmplog_lvl = afl->cmplog_lvl; if (!cmplog_done) { - lvl = 1; + lvl = LVL1; } else { @@ -1610,8 +1641,8 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } - if (cmplog_lvl >= 2 && cmplog_done < 2) { lvl += 2; } - if (cmplog_lvl >= 3 && cmplog_done < 3) { lvl += 4; } + if (cmplog_lvl >= 2 && cmplog_done < 2) { lvl += LVL2; } + if (cmplog_lvl >= 3 && cmplog_done < 3) { lvl += LVL3; } #ifdef COMBINE u8 *cbuf = afl_realloc((void **)&afl->in_scratch_buf, len + 128); @@ -1668,7 +1699,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } - } else if (lvl & 1) { + } else if (lvl & LVL1) { if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, cbuf, len, taint))) { -- cgit v1.2.3 From a9ebf72a8408f993e6279ba853c49e31310cf73f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 18 Jan 2021 22:19:04 +0100 Subject: cmp map memset fix --- src/afl-fuzz-redqueen.c | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 56022fa6..4488d220 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -110,7 +110,7 @@ static struct range *pop_biggest_range(struct range **ranges) { static void dump(char *txt, u8 *buf, u32 len) { u32 i; - fprintf(stderr, "DUMP %s %llx ", txt, hash64(buf, len, HASH_CONST)); + fprintf(stderr, "DUMP %s %016llx ", txt, hash64(buf, len, HASH_CONST)); for (i = 0; i < len; i++) fprintf(stderr, "%02x", buf[i]); fprintf(stderr, "\n"); @@ -255,12 +255,6 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, memcpy(changed, buf, len); type_replace(afl, changed, len); -#ifdef _DEBUG - dump("ORIG", buf, len); - dump("CHAN", changed, len); - fprintf(stderr, "CKSUM %llx (%u)\n", exec_cksum, afl->fsrv.map_size); -#endif - while ((rng = pop_biggest_range(&ranges)) != NULL && afl->stage_cur < afl->stage_max) { @@ -949,8 +943,8 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, if (its_len >= shape) { #ifdef _DEBUG - // fprintf(stderr, "TestUN: %u>=%u (len=%u idx=%u attr=%u off=%lu) (%u) ", - // its_len, shape, len, idx, attr, off, do_reverse); + fprintf(stderr, "TestUN: %u>=%u (len=%u idx=%u attr=%u off=%lu) (%u) ", + its_len, shape, len, idx, attr, off, do_reverse); u32 i; u8 *o_r = (u8 *)&changed_val; for (i = 0; i < shape; i++) @@ -1545,12 +1539,6 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { u8 r = 1; - if (unlikely(!afl->orig_cmp_map)) { - - afl->orig_cmp_map = ck_alloc_nozero(sizeof(struct cmp_map)); - - } - if (unlikely(!afl->pass_stats)) { afl->pass_stats = ck_alloc(sizeof(struct afl_pass_stat) * CMP_MAP_W); @@ -1583,10 +1571,6 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { #endif -#ifdef _DEBUG - dump("NEW ", buf, len); -#endif - } else { buf = afl->queue_cur->cmplog_colorinput; @@ -1611,14 +1595,27 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { #endif // Generate the cmplog data + // manually clear the full cmp_map memset(afl->shm.cmp_map, 0, sizeof(struct cmp_map)); if (unlikely(common_fuzz_cmplog_stuff(afl, orig_buf, len))) { return 1; } + if (unlikely(!afl->orig_cmp_map)) { + + afl->orig_cmp_map = ck_alloc_nozero(sizeof(struct cmp_map)); + + } + memcpy(afl->orig_cmp_map, afl->shm.cmp_map, sizeof(struct cmp_map)); - // manually clear just the headers - memset(afl->shm.cmp_map->headers, 0, sizeof(struct cmp_header)); + memset(afl->shm.cmp_map->headers, 0, sizeof(struct cmp_header) * CMP_MAP_W); if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) { return 1; } +#ifdef _DEBUG + dump("ORIG", orig_buf, len); + dump("NEW ", buf, len); +#endif + + // Start insertion loop + u64 orig_hit_cnt, new_hit_cnt; u64 orig_execs = afl->fsrv.total_execs; orig_hit_cnt = afl->queued_paths + afl->unique_crashes; -- cgit v1.2.3 From e91f3b0de65376b001d45892cc6bdd2fcafde949 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 19 Jan 2021 10:41:42 +0100 Subject: codeql fix --- src/afl-fuzz-run.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index b597488b..17c305ed 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -424,7 +424,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, if (unlikely(afl->fixed_seed)) { - diff_us = (afl->fsrv.exec_tmout - 1) * afl->stage_max; + diff_us = (u64)(afl->fsrv.exec_tmout - 1) * (u64)afl->stage_max; } else { -- cgit v1.2.3 From 95ee2cdd574dabf39d662cd2a76542b733d374ac Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 19 Jan 2021 13:05:42 +0100 Subject: cleanup --- src/afl-fuzz-redqueen.c | 83 ++++++++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 4488d220..1c5b95f6 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -29,7 +29,7 @@ #include "cmplog.h" //#define _DEBUG -//#define COMBINE +#define COMBINE #define CMPLOG_INTROSPECTION //#define ARITHMETIC_LESSER_GREATER @@ -1103,14 +1103,13 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, u32 len, u32 lvl, struct tainted *taint) { struct cmp_header *h = &afl->shm.cmp_map->headers[key]; - struct tainted * t; - u32 i, j, idx, taint_len; - u32 have_taint = 1, is_n = 0; - u32 loggeds = h->hits; - if (h->hits > CMP_MAP_H) { loggeds = CMP_MAP_H; } + // FP handling only from lvl 2 onwards + if ((h->attribute & IS_FP) && lvl < LVL2) { return 0; } - u8 status = 0; - u8 found_one = 0; + struct tainted *t; + u32 i, j, idx, taint_len, loggeds; + u32 have_taint = 1, is_n = 0; + u8 status = 0, found_one = 0; /* loop cmps are useless, detect and ignore them */ #ifdef WORD_SIZE_64 @@ -1121,6 +1120,16 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, u8 s_v0_inc = 1, s_v1_inc = 1; u8 s_v0_dec = 1, s_v1_dec = 1; + if (h->hits > CMP_MAP_H) { + + loggeds = CMP_MAP_H; + + } else { + + loggeds = h->hits; + + } + switch (SHAPE_BYTES(h->shape)) { case 1: @@ -1133,9 +1142,6 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } - // FP handling only from lvl 2 onwards - if ((h->attribute & IS_FP) && lvl < LVL2) return 0; - for (i = 0; i < loggeds; ++i) { struct cmp_operands *o = &afl->shm.cmp_map->log[key][i]; @@ -1742,51 +1748,56 @@ exit_its: } #ifdef COMBINE - // copy the current virgin bits so we can recover the information - u8 *virgin_save = afl_realloc((void **)&afl->eff_buf, afl->shm.map_size); - memcpy(virgin_save, afl->virgin_bits, afl->shm.map_size); - // reset virgin bits to the backup previous to redqueen - memcpy(afl->virgin_bits, virgin_backup, afl->shm.map_size); + if (afl->queued_paths + afl->unique_crashes > orig_hit_cnt + 1) { - u8 status = 0; - its_fuzz(afl, cbuf, len, &status); + // copy the current virgin bits so we can recover the information + u8 *virgin_save = afl_realloc((void **)&afl->eff_buf, afl->shm.map_size); + memcpy(virgin_save, afl->virgin_bits, afl->shm.map_size); + // reset virgin bits to the backup previous to redqueen + memcpy(afl->virgin_bits, virgin_backup, afl->shm.map_size); + + u8 status = 0; + its_fuzz(afl, cbuf, len, &status); // now combine with the saved virgin bits #ifdef WORD_SIZE_64 - u64 *v = (u64 *)afl->virgin_bits; - u64 *s = (u64 *)virgin_save; - u32 i; - for (i = 0; i < (afl->shm.map_size >> 3); i++) { + u64 *v = (u64 *)afl->virgin_bits; + u64 *s = (u64 *)virgin_save; + u32 i; + for (i = 0; i < (afl->shm.map_size >> 3); i++) { - v[i] &= s[i]; + v[i] &= s[i]; - } + } #else - u32 *v = (u64 *)afl->virgin_bits; - u32 *s = (u64 *)virgin_save; - u32 i; - for (i = 0; i < (afl->shm.map_size >> 2); i++) { + u32 *v = (u64 *)afl->virgin_bits; + u32 *s = (u64 *)virgin_save; + u32 i; + for (i = 0; i < (afl->shm.map_size >> 2); i++) { - v[i] &= s[i]; + v[i] &= s[i]; - } + } #endif #ifdef _DEBUG - dump("COMB", cbuf, len); - if (status == 1) { + dump("COMB", cbuf, len); + if (status == 1) { - fprintf(stderr, "NEW COMBINED\n"); + fprintf(stderr, "NEW COMBINED\n"); - } else { + } else { - fprintf(stderr, "NO new combined\n"); + fprintf(stderr, "NO new combined\n"); - } + } #endif + + } + #endif new_hit_cnt = afl->queued_paths + afl->unique_crashes; -- cgit v1.2.3 From 292f91a55f6af5e06b41b429e55f65b7df4d8d16 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 19 Jan 2021 13:16:39 +0100 Subject: tiny scan-build nags fixed --- src/afl-fuzz.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index bb2674f0..e6317f43 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -586,7 +586,7 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->timeout_given) { FATAL("Multiple -t options not supported"); } - if (sscanf(optarg, "%u%c", &afl->fsrv.exec_tmout, &suffix) < 1 || + if (!optarg || sscanf(optarg, "%u%c", &afl->fsrv.exec_tmout, &suffix) < 1 || optarg[0] == '-') { FATAL("Bad syntax used for -t"); @@ -768,7 +768,7 @@ int main(int argc, char **argv_orig, char **envp) { case 'V': { afl->most_time_key = 1; - if (sscanf(optarg, "%llu", &afl->most_time) < 1 || optarg[0] == '-') { + if (!optarg || sscanf(optarg, "%llu", &afl->most_time) < 1 || optarg[0] == '-') { FATAL("Bad syntax used for -V"); @@ -779,7 +779,7 @@ int main(int argc, char **argv_orig, char **envp) { case 'E': { afl->most_execs_key = 1; - if (sscanf(optarg, "%llu", &afl->most_execs) < 1 || optarg[0] == '-') { + if (!optarg || sscanf(optarg, "%llu", &afl->most_execs) < 1 || optarg[0] == '-') { FATAL("Bad syntax used for -E"); -- cgit v1.2.3 From 0367f6c72339ba655956d7e17b0b27c92b22d781 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 19 Jan 2021 14:03:10 +0100 Subject: cleanup and rename _DISCARD->_SKIP --- src/afl-cc.c | 6 +++--- src/afl-fuzz-bitmap.c | 1 - src/afl-fuzz.c | 1 - src/afl-ld-lto.c | 1 - 4 files changed, 3 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 8fb42718..1379488e 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -835,7 +835,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;" "extern \"C\" void __afl_coverage_discard();" - "extern \"C\" void __afl_coverage_abort();" + "extern \"C\" void __afl_coverage_skip();" "extern \"C\" void __afl_coverage_on();" "extern \"C\" void __afl_coverage_off();"; @@ -844,7 +844,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;" "void __afl_coverage_discard();" - "void __afl_coverage_abort();" + "void __afl_coverage_skip();" "void __afl_coverage_on();" "void __afl_coverage_off();"; @@ -857,7 +857,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_OFF()=__afl_coverage_off()"; cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_DISCARD()=__afl_coverage_discard()"; - cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_ABORT()=__afl_coverage_abort()"; + cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_SKIP()=__afl_coverage_skip()"; cc_params[cc_par_cnt++] = "-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : " "__afl_fuzz_alt_ptr)"; diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index ed8c2510..586f3990 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -703,7 +703,6 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (!classified) { classify_counts(&afl->fsrv); - // classified = 1; } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e6317f43..7facf261 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -337,7 +337,6 @@ int main(int argc, char **argv_orig, char **envp) { if (get_afl_env("AFL_DEBUG")) { debug = afl->debug = 1; } - // map_size = get_map_size(); afl_state_init(afl, map_size); afl->debug = debug; afl_fsrv_init(&afl->fsrv); diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index 7a4d9132..0671d1c4 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -253,7 +253,6 @@ static void edit_params(int argc, char **argv) { int main(int argc, char **argv) { s32 pid, i, status; - // u8 * ptr; char thecwd[PATH_MAX]; if (getenv("AFL_LD_CALLER") != NULL) { -- cgit v1.2.3 From e7b572af3608e2d097aad17408ad4853befdc02c Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 20 Jan 2021 01:49:32 +0100 Subject: bugfix and new transform detection feature --- src/afl-fuzz-redqueen.c | 430 +++++++++++++++++++++++++++++++++++++++++++----- src/afl-fuzz.c | 14 ++ 2 files changed, 403 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 1c5b95f6..bf41863e 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -30,18 +30,21 @@ //#define _DEBUG #define COMBINE -#define CMPLOG_INTROSPECTION +//#define CMPLOG_INTROSPECTION //#define ARITHMETIC_LESSER_GREATER +//#define TRANSFORM // CMP attribute enum enum { - IS_EQUAL = 1, - IS_GREATER = 2, - IS_LESSER = 4, - IS_FP = 8, - IS_FP_MOD = 16, - IS_INT_MOD = 32 + IS_EQUAL = 1, // arithemtic equal comparison + IS_GREATER = 2, // arithmetic greater comparison + IS_LESSER = 4, // arithmetic lesser comparison + IS_FP = 8, // is a floating point, not an integer + /* --- below are internal settings, not from target cmplog */ + IS_FP_MOD = 16, // arithemtic changed floating point + IS_INT_MOD = 32, // arithmetic changed interger + IS_TRANSFORM = 64 // transformed integer }; @@ -466,6 +469,7 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) { } +#ifdef TRANSFORM static int strntoll(const char *str, size_t sz, char **end, int base, long long *out) { @@ -513,6 +517,8 @@ static int strntoull(const char *str, size_t sz, char **end, int base, } +#endif + static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u64 pattern, u64 repl, u64 o_pattern, u64 changed_val, u8 attr, u32 idx, u32 taint_len, @@ -553,14 +559,15 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u32 its_len = MIN(len - idx, taint_len); - u8 * endptr; - u8 use_num = 0, use_unum = 0; - unsigned long long unum; - long long num; - +#ifdef TRANSFORM // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3 if (lvl & LVL3) { + u8 * endptr; + u8 use_num = 0, use_unum = 0; + unsigned long long unum; + long long num; + if (afl->queue_cur->is_ascii) { endptr = buf_8; @@ -575,11 +582,11 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } -#ifdef _DEBUG + #ifdef _DEBUG if (idx == 0) fprintf(stderr, "ASCII is=%u use_num=%u use_unum=%u idx=%u %llx==%llx\n", afl->queue_cur->is_ascii, use_num, use_unum, idx, num, pattern); -#endif + #endif // num is likely not pattern as atoi("AAA") will be zero... if (use_num && ((u64)num == pattern || !num)) { @@ -626,8 +633,201 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } + // Try to identify transform magic + if (pattern != o_pattern && repl == changed_val && attr <= IS_EQUAL) { + + u64 *ptr = (u64 *)&buf[idx]; + u64 *o_ptr = (u64 *)&orig_buf[idx]; + u64 b_val, o_b_val, mask; + + switch (SHAPE_BYTES(h->shape)) { + + case 0: + case 1: + b_val = (u64)(*ptr % 0x100); + o_b_val = (u64)(*o_ptr % 0x100); + mask = 0xff; + break; + case 2: + case 3: + b_val = (u64)(*ptr % 0x10000); + o_b_val = (u64)(*o_ptr % 0x10000); + mask = 0xffff; + break; + case 4: + case 5: + case 6: + case 7: + b_val = (u64)(*ptr % 0x100000000); + o_b_val = (u64)(*o_ptr % 0x100000000); + mask = 0xffffffff; + break; + default: + b_val = *ptr; + o_b_val = *o_ptr; + mask = 0xffffffffffffffff; + + } + + // test for arithmetic, eg. "if ((user_val - 0x1111) == 0x1234) ..." + s64 diff = pattern - b_val; + s64 o_diff = o_pattern - o_b_val; + /* + fprintf(stderr, "DIFF1 idx=%03u shape=%02u %llx-%llx=%lx\n", idx, + h->shape + 1, o_pattern, o_b_val, o_diff); + fprintf(stderr, "DIFF1 %016llx %llx-%llx=%lx\n", repl, pattern, + b_val, diff);*/ + if (diff == o_diff && diff) { + + // this could be an arithmetic transformation + + u64 new_repl = (u64)((s64)repl - diff); + // fprintf(stderr, "SAME DIFF %llx->%llx\n", repl, new_repl); + + if (unlikely(cmp_extend_encoding( + afl, h, pattern, new_repl, o_pattern, repl, IS_TRANSFORM, idx, + taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { + + return 1; + + } + + if (*status == 1) { fprintf(stderr, "FOUND!\n"); } + + } + + // test for XOR, eg. "if ((user_val ^ 0xabcd) == 0x1234) ..." + if (*status != 1) { + + diff = pattern ^ b_val; + s64 o_diff = o_pattern ^ o_b_val; + + /* fprintf(stderr, "DIFF2 idx=%03u shape=%02u %llx-%llx=%lx\n", + idx, h->shape + 1, o_pattern, o_b_val, o_diff); fprintf(stderr, + "DIFF2 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);*/ + if (diff == o_diff && diff) { + + // this could be a XOR transformation + + u64 new_repl = (u64)((s64)repl ^ diff); + // fprintf(stderr, "SAME DIFF %llx->%llx\n", repl, new_repl); + + if (unlikely(cmp_extend_encoding( + afl, h, pattern, new_repl, o_pattern, repl, IS_TRANSFORM, idx, + taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { + + return 1; + + } + + if (*status == 1) { fprintf(stderr, "FOUND!\n"); } + + } + + } + + // test for to lowercase, eg. "new_val = (user_val | 0x2020) ..." + if (*status != 1) { + + if ((b_val | (0x2020202020202020 & mask)) == (pattern & mask)) { + + diff = 1; + + } else { + + diff = 0; + + } + + if ((o_b_val | (0x2020202020202020 & mask)) == (o_pattern & mask)) { + + o_diff = 1; + + } else { + + diff = 0; + + } + + /* fprintf(stderr, "DIFF3 idx=%03u shape=%02u %llx-%llx=%lx\n", + idx, h->shape + 1, o_pattern, o_b_val, o_diff); fprintf(stderr, + "DIFF3 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);*/ + if (o_diff && diff) { + + // this could be a lower to upper + + u64 new_repl = (repl & (0x5f5f5f5f5f5f5f5f & mask)); + // fprintf(stderr, "SAME DIFF %llx->%llx\n", repl, new_repl); + + if (unlikely(cmp_extend_encoding( + afl, h, pattern, new_repl, o_pattern, repl, IS_TRANSFORM, idx, + taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { + + return 1; + + } + + if (*status == 1) { fprintf(stderr, "FOUND!\n"); } + + } + + } + + // test for to uppercase, eg. "new_val = (user_val | 0x5f5f) ..." + if (*status != 1) { + + if ((b_val & (0x5f5f5f5f5f5f5f5f & mask)) == (pattern & mask)) { + + diff = 1; + + } else { + + diff = 0; + + } + + if ((o_b_val & (0x5f5f5f5f5f5f5f5f & mask)) == (o_pattern & mask)) { + + o_diff = 1; + + } else { + + o_diff = 0; + + } + + /* fprintf(stderr, "DIFF4 idx=%03u shape=%02u %llx-%llx=%lx\n", + idx, h->shape + 1, o_pattern, o_b_val, o_diff); fprintf(stderr, + "DIFF4 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);*/ + if (o_diff && diff) { + + // this could be a lower to upper + + u64 new_repl = (repl | (0x2020202020202020 & mask)); + // fprintf(stderr, "SAME DIFF %llx->%llx\n", repl, new_repl); + + if (unlikely(cmp_extend_encoding( + afl, h, pattern, new_repl, o_pattern, repl, IS_TRANSFORM, idx, + taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { + + return 1; + + } + + if (*status == 1) { fprintf(stderr, "FOUND!\n"); } + + } + + } + + *status = 0; + + } + } +#endif + // we only allow this for ascii2integer (above) if (unlikely(pattern == o_pattern)) { return 0; } @@ -783,7 +983,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // in original buffer) #ifdef ARITHMETIC_LESSER_GREATER - if (lvl < LVL3) { return 0; } + if (lvl < LVL3 || attr == IS_TRANSFORM) { return 0; } // lesser/greater FP comparison if ((attr & (IS_LESSER + IS_GREATER)) && @@ -1374,56 +1574,185 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, - u8 *o_pattern, u32 idx, u32 taint_len, - u8 *orig_buf, u8 *buf, u8 *cbuf, u32 len, - u8 *status) { + u8 *o_pattern, u8 *changed_val, u32 idx, + u32 taint_len, u8 *orig_buf, u8 *buf, u8 *cbuf, + u32 len, u8 lvl, u8 *status) { #ifndef COMBINE (void)(cbuf); #endif - u32 i; + u32 i = 0; u32 its_len = MIN((u32)32, len - idx); its_len = MIN(its_len, taint_len); u8 save[32]; memcpy(save, &buf[idx], its_len); - for (i = 0; i < its_len; ++i) { + if (lvl == LVL1) { - if ((pattern[i] != buf[idx + i] && o_pattern[i] != orig_buf[idx + i]) || - *status == 1) { + for (i = 0; i < its_len; ++i) { - break; + if ((pattern[i] != buf[idx + i] && o_pattern[i] != orig_buf[idx + i]) || + *status == 1) { + + break; + + } + + buf[idx + i] = repl[i]; + + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + +#ifdef COMBINE + if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i); } +#endif } - buf[idx + i] = repl[i]; + } + + if (*status == 1) return 0; + + if (lvl & LVL3) { + + u8 toupper = 0, tolower = 0, xor = 0, arith = 0; + u8 xor_val[32], arith_val[32]; + u32 j; + +#ifdef _DEBUG + fprintf(stderr, "RTN TRANSFORM idx=%u ", idx); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", orig_buf[idx + j]); + fprintf(stderr, " -> "); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", o_pattern[j]); + fprintf(stderr, " <= "); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", repl[j]); + fprintf(stderr, "\n"); + fprintf(stderr, " "); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", buf[idx + j]); + fprintf(stderr, " -> "); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", pattern[j]); + fprintf(stderr, " <= "); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", changed_val[j]); + fprintf(stderr, "\n"); +#endif + for (i = 0; i < its_len; ++i) { + + xor_val[i] = pattern[i] ^ buf[idx + i]; + arith_val[i] = pattern[i] - buf[idx + i]; + + if ((o_pattern[i] ^ orig_buf[idx + i]) == xor_val[i] && xor_val[i]) { + + ++xor; + + } + + if ((o_pattern[i] - orig_buf[idx + i]) == arith_val[i] && arith_val[i]) { + + ++arith; + + } + + if ((buf[idx + i] | 0x20) == pattern[i] && + (orig_buf[idx + i] | 0x20) == o_pattern[i]) { + + ++tolower; - if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + } + + if ((buf[idx + i] & 0x5a) == pattern[i] && + (orig_buf[idx + i] & 0x5a) == o_pattern[i]) { + + ++toupper; + + } + +#ifdef _DEBUG + fprintf(stderr, "RTN loop=%u %u %u %u %u (%u %u)\n", i, xor, arith, + tolower, toupper, arith_val[i], xor_val[i]); +#endif + + if (xor > i) { + + for (j = 0; j <= i; j++) + buf[idx + j] = repl[j] ^ xor_val[j]; + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + // fprintf(stderr, "RTN ATTEMPT xor %u result %u\n", xor, *status); + + } + + if (arith > i && *status != 1) { + + for (j = 0; j <= i; j++) + buf[idx + j] = repl[j] - arith_val[j]; + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + // fprintf(stderr, "RTN ATTEMPT arith %u result %u\n", arith, *status); + + } + + if (toupper > i && *status != 1) { + + for (j = 0; j <= i; j++) + buf[idx + j] = repl[j] | 0x20; + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + // fprintf(stderr, "RTN ATTEMPT toupper %u result %u\n", toupper, + // *status); + + } + + if (tolower > i && *status != 1) { + + for (j = 0; j <= i; j++) + buf[idx + j] = repl[j] & 0x5f; + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + // fprintf(stderr, "RTN ATTEMPT tolower %u result %u\n", tolower, + // *status); + + } #ifdef COMBINE - if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i); } + if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i); } #endif + if ((i >= xor&&i >= arith &&i >= tolower &&i >= toupper) || + repl[i] != changed_val[i] || *status == 1) { + + break; + + } + + } + } memcpy(&buf[idx], save, i); + return 0; } static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, - u32 len, struct tainted *taint) { + u32 len, u8 lvl, struct tainted *taint) { struct tainted * t; struct cmp_header *h = &afl->shm.cmp_map->headers[key]; - u32 i, j, idx, have_taint = 1, taint_len; + u32 i, j, idx, have_taint = 1, taint_len, loggeds; + u8 status = 0, found_one = 0; - u32 loggeds = h->hits; - if (h->hits > CMP_MAP_RTN_H) { loggeds = CMP_MAP_RTN_H; } + if (h->hits > CMP_MAP_RTN_H) { - u8 status = 0; - u8 found_one = 0; + loggeds = CMP_MAP_RTN_H; + + } else { + + loggeds = h->hits; + + } for (i = 0; i < loggeds; ++i) { @@ -1445,6 +1774,20 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } + /* + struct cmp_header *hh = &afl->orig_cmp_map->headers[key]; + fprintf(stderr, "RTN N hits=%u id=%u shape=%u attr=%u v0=", h->hits, h->id, + h->shape, h->attribute); for (j = 0; j < 8; j++) fprintf(stderr, "%02x", + o->v0[j]); fprintf(stderr, " v1="); for (j = 0; j < 8; j++) fprintf(stderr, + "%02x", o->v1[j]); fprintf(stderr, "\nRTN O hits=%u id=%u shape=%u attr=%u + o0=", hh->hits, hh->id, hh->shape, hh->attribute); for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", orig_o->v0[j]); + fprintf(stderr, " o1="); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", orig_o->v1[j]); + fprintf(stderr, "\n"); + */ + t = taint; while (t->next) { @@ -1476,9 +1819,9 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, status = 0; - if (unlikely(rtn_extend_encoding(afl, o->v0, o->v1, orig_o->v0, idx, - taint_len, orig_buf, buf, cbuf, len, - &status))) { + if (unlikely(rtn_extend_encoding(afl, o->v0, o->v1, orig_o->v0, + orig_o->v1, idx, taint_len, orig_buf, + buf, cbuf, len, lvl, &status))) { return 1; @@ -1493,9 +1836,9 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, status = 0; - if (unlikely(rtn_extend_encoding(afl, o->v1, o->v0, orig_o->v1, idx, - taint_len, orig_buf, buf, cbuf, len, - &status))) { + if (unlikely(rtn_extend_encoding(afl, o->v1, o->v0, orig_o->v1, + orig_o->v0, idx, taint_len, orig_buf, + buf, cbuf, len, lvl, &status))) { return 1; @@ -1511,7 +1854,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } // If failed, add to dictionary - if (!found_one) { + if (!found_one && (lvl & LVL1)) { if (unlikely(!afl->pass_stats[key].total)) { @@ -1702,9 +2045,14 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } - } else if (lvl & LVL1) { + } else if ((lvl & LVL1) + +#ifdef TRANSFORM + || (lvl & LVL3) +#endif + ) { - if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, cbuf, len, taint))) { + if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, cbuf, len, lvl, taint))) { goto exit_its; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 88c40ee8..0f76e8a3 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1515,7 +1515,21 @@ int main(int argc, char **argv_orig, char **envp) { } + u8 *save_env = NULL; + if (afl->cmplog_binary) { + + save_env = ck_strdup(getenv(CMPLOG_SHM_ENV_VAR)); + unsetenv(CMPLOG_SHM_ENV_VAR); // normal forkserver should not have this + + } + perform_dry_run(afl); + if (save_env) { + + setenv(CMPLOG_SHM_ENV_VAR, save_env, 1); // needed for at_exit() + ck_free(save_env); + + } /* if (!user_set_cache && afl->q_testcase_max_cache_size) { -- cgit v1.2.3 From 0306261fec4c9ebc2b1361da1d0fbbe9bade8847 Mon Sep 17 00:00:00 2001 From: Joey Jiao Date: Wed, 13 Jan 2021 12:32:36 +0800 Subject: Fix build error for Android - LTO not work yet --- src/afl-analyze.c | 3 --- src/afl-fuzz-stats.c | 4 ++++ src/afl-gotcpu.c | 3 --- src/afl-showmap.c | 3 --- src/afl-tmin.c | 4 ---- 5 files changed, 4 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 8fc4434a..0af489fe 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -26,9 +26,6 @@ #define AFL_MAIN -#ifdef __ANDROID__ - #include "android-ashmem.h" -#endif #include "config.h" #include "types.h" #include "debug.h" diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index e86f2aeb..e67bace9 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -58,7 +58,11 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { for (i = 0; i < argc; ++i) { if (i) fprintf(f, " "); +#ifdef __ANDROID__ + if (memchr(argv[i], '\'', sizeof(argv[i]))) { +#else if (index(argv[i], '\'')) { +#endif fprintf(f, "'"); for (j = 0; j < strlen(argv[i]); j++) diff --git a/src/afl-gotcpu.c b/src/afl-gotcpu.c index 1aea3e40..ac002a93 100644 --- a/src/afl-gotcpu.c +++ b/src/afl-gotcpu.c @@ -35,9 +35,6 @@ #define _GNU_SOURCE #endif -#ifdef __ANDROID__ - #include "android-ashmem.h" -#endif #include #include #include diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 5c9d38e0..6d95fc1d 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -31,9 +31,6 @@ #define AFL_MAIN -#ifdef __ANDROID__ - #include "android-ashmem.h" -#endif #include "config.h" #include "types.h" #include "debug.h" diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 6e2d7708..5fd60cd2 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -29,10 +29,6 @@ #define AFL_MAIN -#ifdef __ANDROID__ - #include "android-ashmem.h" -#endif - #include "config.h" #include "types.h" #include "debug.h" -- cgit v1.2.3 From ac1117ffaeec0bd3c593063a05d8aa000d162d47 Mon Sep 17 00:00:00 2001 From: Joey Jiao Date: Tue, 19 Jan 2021 09:44:59 +0800 Subject: android: Fix runtime for mutator --- src/afl-cc.c | 14 ++++++++++---- src/afl-fuzz-mutators.c | 5 ++++- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 1379488e..f3dfd49f 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -586,6 +586,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (instrument_mode == INSTRUMENT_PCGUARD) { #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) +#ifdef __ANDROID__ + cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; +#else if (have_instr_list) { if (!be_quiet) @@ -605,6 +608,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } +#endif #else #if LLVM_MAJOR >= 4 if (!be_quiet) @@ -1034,6 +1038,10 @@ int main(int argc, char **argv, char **envp) { #endif +#ifdef __ANDROID__ + have_llvm = 1; +#endif + if ((ptr = find_object("afl-gcc-pass.so", argv[0])) != NULL) { have_gcc_plugin = 1; @@ -1807,11 +1815,8 @@ int main(int argc, char **argv, char **envp) { if (!be_quiet && cmplog_mode) printf("CmpLog mode by \n"); -#ifdef __ANDROID__ - ptr = find_object("afl-compiler-rt.so", argv[0]); -#else +#ifndef __ANDROID__ ptr = find_object("afl-compiler-rt.o", argv[0]); -#endif if (!ptr) { @@ -1824,6 +1829,7 @@ int main(int argc, char **argv, char **envp) { if (debug) { DEBUGF("rt=%s obj_path=%s\n", ptr, obj_path); } ck_free(ptr); +#endif edit_params(argc, argv, envp); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 089707b9..80df6d08 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -141,7 +141,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { struct custom_mutator *mutator = ck_alloc(sizeof(struct custom_mutator)); mutator->name = fn; - mutator->name_short = strrchr(fn, '/') + 1; + if (memchr(fn, '/', strlen(fn))) + mutator->name_short = strrchr(fn, '/') + 1; + else + mutator->name_short = strdup(fn); ACTF("Loading custom mutator library from '%s'...", fn); dh = dlopen(fn, RTLD_NOW); -- cgit v1.2.3 From 9dff3495d54c0bd3da59ef43ca25df06c6d9f2c2 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 20 Jan 2021 10:01:34 +0100 Subject: better cmp map fsrv fix --- src/afl-forkserver.c | 4 +++- src/afl-fuzz-cmplog.c | 2 ++ src/afl-fuzz.c | 14 -------------- 3 files changed, 5 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 39f044f2..c1b3d02f 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -58,7 +58,9 @@ static list_t fsrv_list = {.element_prealloc_count = 0}; static void fsrv_exec_child(afl_forkserver_t *fsrv, char **argv) { - if (fsrv->qemu_mode) setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); + if (fsrv->qemu_mode) { setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); } + + unsetenv(CMPLOG_SHM_ENV_VAR); // we do not want that in non-cmplog fsrv execv(fsrv->target_path, argv); diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c index 8ffc6e1b..27c6c413 100644 --- a/src/afl-fuzz-cmplog.c +++ b/src/afl-fuzz-cmplog.c @@ -33,6 +33,8 @@ void cmplog_exec_child(afl_forkserver_t *fsrv, char **argv) { setenv("___AFL_EINS_ZWEI_POLIZEI___", "1", 1); + if (fsrv->qemu_mode) { setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); } + if (!fsrv->qemu_mode && argv[0] != fsrv->cmplog_binary) { argv[0] = fsrv->cmplog_binary; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 0f76e8a3..88c40ee8 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1515,21 +1515,7 @@ int main(int argc, char **argv_orig, char **envp) { } - u8 *save_env = NULL; - if (afl->cmplog_binary) { - - save_env = ck_strdup(getenv(CMPLOG_SHM_ENV_VAR)); - unsetenv(CMPLOG_SHM_ENV_VAR); // normal forkserver should not have this - - } - perform_dry_run(afl); - if (save_env) { - - setenv(CMPLOG_SHM_ENV_VAR, save_env, 1); // needed for at_exit() - ck_free(save_env); - - } /* if (!user_set_cache && afl->q_testcase_max_cache_size) { -- cgit v1.2.3 From f380487bb49a66b1fac513cad344f1be5df10959 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 20 Jan 2021 13:51:57 +0100 Subject: wip --- src/afl-fuzz-redqueen.c | 518 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 452 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index bf41863e..7ac0290a 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -517,6 +517,149 @@ static int strntoull(const char *str, size_t sz, char **end, int base, } +static u8 hex_table_up[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; +static u8 hex_table_low[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; +static u8 hex_table[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, + 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15}; + +// tests 2 bytes at location +static int is_hex(const char *str) { + + u32 i; + + for (i = 0; i < 2; i++) { + + switch (str[i]) { + + case '0' ... '9': + case 'A' ... 'F': + case 'a' ... 'f': + break; + default: + return 0; + + } + + } + + return 1; + +} + +// tests 4 bytes at location +static int is_base64(const char *str) { + + u32 i; + + for (i = 0; i < 4; i++) { + + switch (str[i]) { + + case '0' ... '9': + case 'A' ... 'Z': + case 'a' ... 'z': + case '+': + case '/': + break; + default: + return 0; + + } + + } + + return 1; + +} + +static u8 base64_encode_table[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static u8 base64_decode_table[] = { + 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51}; + +static u32 from_base64(u8 *src, u8 *dst, u32 dst_len) { + + u32 i, j, v; + u32 len = ((dst_len / 3) << 2); + u32 ret = 0; + + for (i = 0, j = 0; i < len; i += 4, j += 3) { + + v = base64_decode_table[src[i] - 43]; + v = (v << 6) | base64_decode_table[src[i + 1] - 43]; + v = src[i + 2] == '=' ? v << 6 + : (v << 6) | base64_decode_table[src[i + 2] - 43]; + v = src[i + 3] == '=' ? v << 6 + : (v << 6) | base64_decode_table[src[i + 3] - 43]; + + dst[j] = (v >> 16) & 0xFF; + ++ret; + + if (src[i + 2] != '=') { + + dst[j + 1] = (v >> 8) & 0xFF; + ++ret; + + } + + if (src[i + 3] != '=') { + + dst[j + 2] = v & 0xFF; + ++ret; + + } + + } + + return ret; + +} + +static void to_base64(u8 *src, u8 *dst, u32 dst_len) { + + u32 i, j, v; + u32 len = (dst_len >> 2) * 3; + + for (i = 0, j = 0; i < len; i += 3, j += 4) { + + v = src[i]; + v = i + 1 < len ? v << 8 | src[i + 1] : v << 8; + v = i + 2 < len ? v << 8 | src[i + 2] : v << 8; + + dst[j] = base64_encode_table[(v >> 18) & 0x3F]; + dst[j + 1] = base64_encode_table[(v >> 12) & 0x3F]; + if (i + 1 < len) { + + dst[j + 2] = base64_encode_table[(v >> 6) & 0x3F]; + + } else { + + dst[j + 2] = '='; + + } + + if (i + 2 < len) { + + dst[j + 3] = base64_encode_table[v & 0x3F]; + + } else { + + dst[j + 3] = '='; + + } + + } + +} + #endif static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, @@ -525,29 +668,6 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u8 *orig_buf, u8 *buf, u8 *cbuf, u32 len, u8 do_reverse, u8 lvl, u8 *status) { - // (void)(changed_val); // TODO - // we can use the information in changed_val to see if there is a - // computable i2s transformation. - // if (pattern != o_pattern && repl != changed_val) { - - // u64 in_diff = pattern - o_pattern, out_diff = repl - changed_val; - // if (in_diff != out_diff) { - - // switch(in_diff) { - - // detect uppercase <-> lowercase, base64, hex encoding, etc.: - // repl = reverse_transform(TYPE, pattern); - // } - // } - // } - // not 100% but would have a chance to be detected - - // fprintf(stderr, - // "Encode: %llx->%llx into %llx(<-%llx) at idx=%u " - // "taint_len=%u shape=%u attr=%u\n", - // o_pattern, pattern, repl, changed_val, idx, taint_len, - // h->shape + 1, attr); - u64 *buf_64 = (u64 *)&buf[idx]; u32 *buf_32 = (u32 *)&buf[idx]; u16 *buf_16 = (u16 *)&buf[idx]; @@ -559,6 +679,12 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u32 its_len = MIN(len - idx, taint_len); + // fprintf(stderr, + // "Encode: %llx->%llx into %llx(<-%llx) at idx=%u " + // "taint_len=%u shape=%u attr=%u\n", + // o_pattern, pattern, repl, changed_val, idx, taint_len, + // h->shape + 1, attr); + #ifdef TRANSFORM // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3 if (lvl & LVL3) { @@ -1581,71 +1707,215 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, #ifndef COMBINE (void)(cbuf); #endif +#ifndef TRANSFORM + (void)(changed_val); +#endif - u32 i = 0; + u8 save[40]; + u32 saved_idx = idx, pre, from = 0, to = 0, i; u32 its_len = MIN((u32)32, len - idx); its_len = MIN(its_len, taint_len); - u8 save[32]; - memcpy(save, &buf[idx], its_len); + u32 saved_its_len = its_len; - if (lvl == LVL1) { + if (lvl & LVL3) { - for (i = 0; i < its_len; ++i) { + u32 max_to = MIN(4U, idx); + if (!(lvl & LVL1) && max_to) { from = 1; } + to = max_to; - if ((pattern[i] != buf[idx + i] && o_pattern[i] != orig_buf[idx + i]) || - *status == 1) { + } - break; + memcpy(save, &buf[saved_idx - to], its_len + to); - } +#ifdef _DEBUG + fprintf(stderr, "RTN TRANSFORM idx=%u lvl=%02x", idx, lvl); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", orig_buf[idx + j]); + fprintf(stderr, " -> "); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", o_pattern[j]); + fprintf(stderr, " <= "); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", repl[j]); + fprintf(stderr, "\n"); + fprintf(stderr, " "); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", buf[idx + j]); + fprintf(stderr, " -> "); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", pattern[j]); + fprintf(stderr, " <= "); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", changed_val[j]); + fprintf(stderr, "\n"); +#endif - buf[idx + i] = repl[i]; + // Try to match the replace value up to 4 bytes before the current idx. + // This allows matching of eg.: + // if (memcmp(user_val, "TEST") == 0) + // if (memcmp(user_val, "TEST-VALUE") == 0) ... + // We only do this in lvl 3, otherwise we only do direct matching - if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + for (pre = from; pre <= to; pre++) { + + if (*status != 1 && (!pre || !memcmp(buf + saved_idx - pre, repl, pre))) { + + idx = saved_idx - pre; + its_len = saved_its_len + pre; + + for (i = 0; i < its_len; ++i) { + + if ((pattern[i] != buf[idx + i] && o_pattern[i] != orig_buf[idx + i]) || + *status == 1) { + + break; + + } + + buf[idx + i] = repl[i]; + + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } #ifdef COMBINE - if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i); } + if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i); } #endif + } + + memcpy(&buf[idx], save + to - pre, i); + } } +#ifdef TRANSFORM + if (*status == 1) return 0; if (lvl & LVL3) { - u8 toupper = 0, tolower = 0, xor = 0, arith = 0; - u8 xor_val[32], arith_val[32]; u32 j; + u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, tob64 = 0; + u32 fromhex = 0, fromb64 = 0; + u32 from_0 = 0, from_x = 0, from_X = 0, from_slash = 0, from_lf = 0, + from_cr = 0, from_up = 0; + u32 to_0 = 0, to_x = 0, to_slash = 0, to_lf = 0, to_cr = 0, to_up = 0; + u8 xor_val[32], arith_val[32], tmp[48]; + + idx = saved_idx; + its_len = saved_its_len; + + memcpy(save, &buf[idx], its_len); -#ifdef _DEBUG - fprintf(stderr, "RTN TRANSFORM idx=%u ", idx); - for (j = 0; j < 8; j++) - fprintf(stderr, "%02x", orig_buf[idx + j]); - fprintf(stderr, " -> "); - for (j = 0; j < 8; j++) - fprintf(stderr, "%02x", o_pattern[j]); - fprintf(stderr, " <= "); - for (j = 0; j < 8; j++) - fprintf(stderr, "%02x", repl[j]); - fprintf(stderr, "\n"); - fprintf(stderr, " "); - for (j = 0; j < 8; j++) - fprintf(stderr, "%02x", buf[idx + j]); - fprintf(stderr, " -> "); - for (j = 0; j < 8; j++) - fprintf(stderr, "%02x", pattern[j]); - fprintf(stderr, " <= "); - for (j = 0; j < 8; j++) - fprintf(stderr, "%02x", changed_val[j]); - fprintf(stderr, "\n"); -#endif for (i = 0; i < its_len; ++i) { xor_val[i] = pattern[i] ^ buf[idx + i]; arith_val[i] = pattern[i] - buf[idx + i]; + if (i == 0) { + + if (orig_buf[idx] == '0') { + + from_0 = 1; + + } else if (orig_buf[idx] == '\\') { + + from_slash = 1; + + } + + if (repl[0] == '0') { + + to_0 = 1; + + } else if (repl[0] == '\\') { + + to_slash = 1; + + } + + } else if (i == 1) { + + if (orig_buf[idx + 1] == 'x') { + + from_x = 1; + + } else if (orig_buf[idx + 1] == 'X') { + + from_X = from_x = 1; + + } + + if (repl[1] == 'x' || repl[1] == 'X') { to_x = 1; } + + } else { + + if (orig_buf[idx + i] == '\n') { ++from_lf; } + if (orig_buf[idx + i] == '\r') { ++from_cr; } + if (repl[i] == '\n') { ++to_lf; } + if (repl[i] == '\r') { ++to_cr; } + + } + + if (i) { + + if (!(i % 2)) { + + if (i < 16 && is_hex(repl + (i << 1))) { + + tohex += 2; + + if (!to_up) { + + if (repl[i] >= 'A' && repl[i] <= 'F') + to_up = 1; + else if (repl[i] >= 'a' && repl[i] <= 'f') + to_up = 2; + if (repl[i - 1] >= 'A' && repl[i - 1] <= 'F') + to_up = 1; + else if (repl[i - 1] >= 'a' && repl[i - 1] <= 'f') + to_up = 2; + + } + + } + + if (len > idx + i && is_hex(orig_buf + idx + i)) { + + fromhex += 2; + + if (!from_up) { + + if (orig_buf[idx + i] >= 'A' && orig_buf[idx + i] <= 'F') + from_up = 1; + else if (orig_buf[idx + i] >= 'a' && orig_buf[idx + i] <= 'f') + from_up = 2; + if (orig_buf[idx + i - 1] >= 'A' && orig_buf[idx + i - 1] <= 'F') + from_up = 1; + else if (orig_buf[idx + i - 1] >= 'a' && + orig_buf[idx + i - 1] <= 'f') + from_up = 2; + + } + + } + + } + + if (!(i % 3) && i + to_lf + to_cr < 24) { + + if (is_base64(repl + i + to_lf + to_cr)) tob64 += 3; + + } + + if (!(i % 4) && i < 24) { + + if (is_base64(orig_buf + idx + i)) fromb64 += 4; + + } + + } + if ((o_pattern[i] ^ orig_buf[idx + i]) == xor_val[i] && xor_val[i]) { ++xor; @@ -1672,10 +1942,124 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } -#ifdef _DEBUG - fprintf(stderr, "RTN loop=%u %u %u %u %u (%u %u)\n", i, xor, arith, - tolower, toupper, arith_val[i], xor_val[i]); -#endif + // #ifdef _DEBUG + fprintf( + stderr, + "RTN loop=%u xor=%u arith=%u tolower=%u toupper=%u tohex=%u tob64=%u " + "fromhex=%u fromb64=%u to_0=%u to_slash=%u to_x=%u to_lf=%u to_cr=%u " + "from_0=%u from_slash=%u from_x=%u from_lf=%u from_cr=%u\n", + i, xor, arith, tolower, toupper, tohex, tob64, fromhex, fromb64, to_0, + to_slash, to_x, to_lf, to_cr, from_0, from_slash, from_x, from_lf, + from_cr); + // #endif + + // input is base64 and converted to binary? convert repl to base64! + if (i && !(i % 4) && i < 24 && fromb64 > i) { + + to_base64(repl, tmp, i); + memcpy(buf + idx, tmp, i); + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + fprintf(stderr, "RTN ATTEMPT fromb64 %u result %u\n", fromb64, *status); + + } + + // input is converted to base64? decode repl with base64! + if (i && !(i % 3) && i < 24 && tob64 > i) { + + u32 olen = from_base64(repl, tmp, i); + memcpy(buf + idx, tmp, olen); + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + fprintf(stderr, "RTN ATTEMPT tob64 %u result %u\n", tob64, *status); + + } + + // input is converted to hex? convert repl to binary! + if (i && !(i % 2) && i < 16 && tohex && tohex > i) { + + u32 off; + if (to_slash + to_x + to_0 == 2) { + + off = 2; + + } else { + + off = 0; + + } + + for (j = 0; j < i / 2; j++) + tmp[j] = (hex_table[repl[off + (j << 1)] - '0'] << 4) + + hex_table[repl[off + (j << 1) + 1] - '0']; + + memcpy(buf + idx, tmp, i / 2); + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + fprintf(stderr, "RTN ATTEMPT tohex %u result %u\n", tohex, *status); + + } + + // input is hex and converted to binary? convert repl to hex! + if (i && !(i % 2) && i < 16 && fromhex && + fromhex + from_slash + from_x + from_0 > i) { + + u8 off = 0; + if (from_slash && from_x) { + + tmp[0] = '\\'; + if (from_X) { + + tmp[1] = 'X'; + + } else { + + tmp[1] = 'x'; + + } + + off = 2; + + } else if (from_0 && from_x) { + + tmp[0] = '0'; + if (from_X) { + + tmp[1] = 'X'; + + } else { + + tmp[1] = 'x'; + + } + + off = 2; + + } + + if (to_up == 1) { + + for (j = 0; j <= i; j++) { + + tmp[off + (j << 1)] = hex_table_up[repl[j] >> 4]; + tmp[off + (j << 1) + 1] = hex_table_up[repl[j] % 16]; + + } + + } else { + + for (j = 0; j <= i; j++) { + + tmp[off + (j << 1)] = hex_table_low[repl[j] >> 4]; + tmp[off + (j << 1) + 1] = hex_table_low[repl[j] % 16]; + + } + + } + + memcpy(buf + idx, tmp, (i << 1) + off); + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + fprintf(stderr, "RTN ATTEMPT fromhex %u result %u\n", fromhex, *status); + memcpy(buf + idx, save, (i << 1) + off); + + } if (xor > i) { @@ -1715,9 +2099,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } -#ifdef COMBINE + #ifdef COMBINE if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i); } -#endif + #endif if ((i >= xor&&i >= arith &&i >= tolower &&i >= toupper) || repl[i] != changed_val[i] || *status == 1) { @@ -1728,9 +2112,11 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } + memcpy(&buf[idx], save, i); + } - memcpy(&buf[idx], save, i); +#endif return 0; -- cgit v1.2.3 From d20a50a41307a7af346e69c93c8b30a3f369a2d4 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 20 Jan 2021 20:59:17 +0100 Subject: hex en/decode works now --- src/afl-forkserver.c | 8 +++-- src/afl-fuzz-redqueen.c | 85 ++++++++++++++++++++++++++----------------------- 2 files changed, 51 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index c1b3d02f..50e4139b 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -59,8 +59,6 @@ static list_t fsrv_list = {.element_prealloc_count = 0}; static void fsrv_exec_child(afl_forkserver_t *fsrv, char **argv) { if (fsrv->qemu_mode) { setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); } - - unsetenv(CMPLOG_SHM_ENV_VAR); // we do not want that in non-cmplog fsrv execv(fsrv->target_path, argv); @@ -398,6 +396,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, struct rlimit r; + if (!fsrv->cmplog_binary && fsrv->qemu_mode == false) { + + unsetenv(CMPLOG_SHM_ENV_VAR); // we do not want that in non-cmplog fsrv + + } + /* Umpf. On OpenBSD, the default fd limit for root users is set to soft 128. Let's try to fix that... */ if (!getrlimit(RLIMIT_NOFILE, &r) && r.rlim_cur < FORKSRV_FD + 2) { diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 7ac0290a..96a27f66 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -30,9 +30,9 @@ //#define _DEBUG #define COMBINE -//#define CMPLOG_INTROSPECTION +#define CMPLOG_INTROSPECTION //#define ARITHMETIC_LESSER_GREATER -//#define TRANSFORM +#define TRANSFORM // CMP attribute enum enum { @@ -579,6 +579,7 @@ static int is_base64(const char *str) { static u8 base64_encode_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static u8 base64_decode_table[] = { + 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, @@ -1712,7 +1713,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, #endif u8 save[40]; - u32 saved_idx = idx, pre, from = 0, to = 0, i; + u32 saved_idx = idx, pre, from = 0, to = 0, i, j; u32 its_len = MIN((u32)32, len - idx); its_len = MIN(its_len, taint_len); u32 saved_its_len = its_len; @@ -1728,7 +1729,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, memcpy(save, &buf[saved_idx - to], its_len + to); #ifdef _DEBUG - fprintf(stderr, "RTN TRANSFORM idx=%u lvl=%02x", idx, lvl); + fprintf(stderr, "RTN T idx=%u lvl=%02x ", idx, lvl); for (j = 0; j < 8; j++) fprintf(stderr, "%02x", orig_buf[idx + j]); fprintf(stderr, " -> "); @@ -1738,7 +1739,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, for (j = 0; j < 8; j++) fprintf(stderr, "%02x", repl[j]); fprintf(stderr, "\n"); - fprintf(stderr, " "); + fprintf(stderr, " "); for (j = 0; j < 8; j++) fprintf(stderr, "%02x", buf[idx + j]); fprintf(stderr, " -> "); @@ -1794,7 +1795,6 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, if (lvl & LVL3) { - u32 j; u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, tob64 = 0; u32 fromhex = 0, fromb64 = 0; u32 from_0 = 0, from_x = 0, from_X = 0, from_slash = 0, from_lf = 0, @@ -1857,28 +1857,28 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - if (i) { + if (i < 16 && is_hex(repl + (i << 1))) { - if (!(i % 2)) { + ++tohex; - if (i < 16 && is_hex(repl + (i << 1))) { + if (!to_up) { - tohex += 2; + if (repl[i << 1] >= 'A' && repl[i << 1] <= 'F') + to_up = 1; + else if (repl[i << 1] >= 'a' && repl[i << 1] <= 'f') + to_up = 2; + if (repl[(i << 1) + 1] >= 'A' && repl[(i << 1) + 1] <= 'F') + to_up = 1; + else if (repl[(i << 1) + 1] >= 'a' && repl[(i << 1) + 1] <= 'f') + to_up = 2; - if (!to_up) { + } - if (repl[i] >= 'A' && repl[i] <= 'F') - to_up = 1; - else if (repl[i] >= 'a' && repl[i] <= 'f') - to_up = 2; - if (repl[i - 1] >= 'A' && repl[i - 1] <= 'F') - to_up = 1; - else if (repl[i - 1] >= 'a' && repl[i - 1] <= 'f') - to_up = 2; + } - } + if (i) { - } + if ((i % 2)) { if (len > idx + i && is_hex(orig_buf + idx + i)) { @@ -1902,13 +1902,13 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - if (!(i % 3) && i + to_lf + to_cr < 24) { + if (i % 3 == 2 && i + to_lf + to_cr < 24) { if (is_base64(repl + i + to_lf + to_cr)) tob64 += 3; } - if (!(i % 4) && i < 24) { + if (i % 4 == 3 && i < 24) { if (is_base64(orig_buf + idx + i)) fromb64 += 4; @@ -1956,25 +1956,26 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, // input is base64 and converted to binary? convert repl to base64! if (i && !(i % 4) && i < 24 && fromb64 > i) { - to_base64(repl, tmp, i); - memcpy(buf + idx, tmp, i); + to_base64(repl, tmp, i + 1); + memcpy(buf + idx, tmp, i + 1); if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } - fprintf(stderr, "RTN ATTEMPT fromb64 %u result %u\n", fromb64, *status); + // fprintf(stderr, "RTN ATTEMPT fromb64 %u result %u\n", fromb64, + // *status); } // input is converted to base64? decode repl with base64! if (i && !(i % 3) && i < 24 && tob64 > i) { - u32 olen = from_base64(repl, tmp, i); + u32 olen = from_base64(repl, tmp, i + 1); memcpy(buf + idx, tmp, olen); if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } - fprintf(stderr, "RTN ATTEMPT tob64 %u result %u\n", tob64, *status); + // fprintf(stderr, "RTN ATTEMPT tob64 %u result %u\n", tob64, *status); } // input is converted to hex? convert repl to binary! - if (i && !(i % 2) && i < 16 && tohex && tohex > i) { + if (i < 16 && tohex > i) { u32 off; if (to_slash + to_x + to_0 == 2) { @@ -1987,18 +1988,18 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - for (j = 0; j < i / 2; j++) + for (j = 0; j <= i; j++) tmp[j] = (hex_table[repl[off + (j << 1)] - '0'] << 4) + hex_table[repl[off + (j << 1) + 1] - '0']; - memcpy(buf + idx, tmp, i / 2); + memcpy(buf + idx, tmp, i + 1); if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } - fprintf(stderr, "RTN ATTEMPT tohex %u result %u\n", tohex, *status); + // fprintf(stderr, "RTN ATTEMPT tohex %u result %u\n", tohex, *status); } // input is hex and converted to binary? convert repl to hex! - if (i && !(i % 2) && i < 16 && fromhex && + if (i && (i % 2) && i < 16 && fromhex && fromhex + from_slash + from_x + from_0 > i) { u8 off = 0; @@ -2036,7 +2037,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, if (to_up == 1) { - for (j = 0; j <= i; j++) { + for (j = 0; j <= (i >> 1); j++) { tmp[off + (j << 1)] = hex_table_up[repl[j] >> 4]; tmp[off + (j << 1) + 1] = hex_table_up[repl[j] % 16]; @@ -2045,7 +2046,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } else { - for (j = 0; j <= i; j++) { + for (j = 0; j <= (i >> 1); j++) { tmp[off + (j << 1)] = hex_table_low[repl[j] >> 4]; tmp[off + (j << 1) + 1] = hex_table_low[repl[j] % 16]; @@ -2054,10 +2055,11 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - memcpy(buf + idx, tmp, (i << 1) + off); + memcpy(buf + idx, tmp, i + 1 + off); if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } - fprintf(stderr, "RTN ATTEMPT fromhex %u result %u\n", fromhex, *status); - memcpy(buf + idx, save, (i << 1) + off); + // fprintf(stderr, "RTN ATTEMPT fromhex %u result %u\n", fromhex, + // *status); + memcpy(buf + idx + i, save + i, i + 1 + off); } @@ -2100,10 +2102,13 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } #ifdef COMBINE - if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i); } + if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i + 1); } #endif - if ((i >= xor&&i >= arith &&i >= tolower &&i >= toupper) || + if ((i >= 7 && + (i >= xor&&i >= arith &&i >= tolower &&i >= toupper &&i > tohex &&i > + (1 + fromhex + from_0 + from_x + from_slash) && + i > tob64 + 3 && i > fromb64 + 3)) || repl[i] != changed_val[i] || *status == 1) { break; -- cgit v1.2.3 From cf5fee7c526ff104cc44b0029aad4395342fa4f2 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 20 Jan 2021 21:03:55 +0100 Subject: remove debug output --- src/afl-fuzz-redqueen.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 96a27f66..f958bb71 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -819,7 +819,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - if (*status == 1) { fprintf(stderr, "FOUND!\n"); } + // if (*status == 1) { fprintf(stderr, "FOUND!\n"); } } @@ -847,7 +847,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - if (*status == 1) { fprintf(stderr, "FOUND!\n"); } + // if (*status == 1) { fprintf(stderr, "FOUND!\n"); } } @@ -894,7 +894,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - if (*status == 1) { fprintf(stderr, "FOUND!\n"); } + // if (*status == 1) { fprintf(stderr, "FOUND!\n"); } } @@ -941,7 +941,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - if (*status == 1) { fprintf(stderr, "FOUND!\n"); } + // if (*status == 1) { fprintf(stderr, "FOUND!\n"); } } @@ -1942,7 +1942,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - // #ifdef _DEBUG + #ifdef _DEBUG fprintf( stderr, "RTN loop=%u xor=%u arith=%u tolower=%u toupper=%u tohex=%u tob64=%u " @@ -1951,7 +1951,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, i, xor, arith, tolower, toupper, tohex, tob64, fromhex, fromb64, to_0, to_slash, to_x, to_lf, to_cr, from_0, from_slash, from_x, from_lf, from_cr); - // #endif + #endif // input is base64 and converted to binary? convert repl to base64! if (i && !(i % 4) && i < 24 && fromb64 > i) { -- cgit v1.2.3 From f7c93d741c09f5049e1da4b9d83acabbde104c46 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 21 Jan 2021 03:52:46 +0100 Subject: base64 solving done --- src/afl-fuzz-redqueen.c | 79 +++++++++++++++++++++---------------------------- 1 file changed, 34 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index f958bb71..8ffd39da 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -30,7 +30,7 @@ //#define _DEBUG #define COMBINE -#define CMPLOG_INTROSPECTION +//#define CMPLOG_INTROSPECTION //#define ARITHMETIC_LESSER_GREATER #define TRANSFORM @@ -564,6 +564,7 @@ static int is_base64(const char *str) { case 'a' ... 'z': case '+': case '/': + case '=': break; default: return 0; @@ -1797,9 +1798,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, tob64 = 0; u32 fromhex = 0, fromb64 = 0; - u32 from_0 = 0, from_x = 0, from_X = 0, from_slash = 0, from_lf = 0, - from_cr = 0, from_up = 0; - u32 to_0 = 0, to_x = 0, to_slash = 0, to_lf = 0, to_cr = 0, to_up = 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]; idx = saved_idx; @@ -1848,13 +1848,6 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, if (repl[1] == 'x' || repl[1] == 'X') { to_x = 1; } - } else { - - if (orig_buf[idx + i] == '\n') { ++from_lf; } - if (orig_buf[idx + i] == '\r') { ++from_cr; } - if (repl[i] == '\n') { ++to_lf; } - if (repl[i] == '\r') { ++to_cr; } - } if (i < 16 && is_hex(repl + (i << 1))) { @@ -1876,43 +1869,39 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - if (i) { - - if ((i % 2)) { - - if (len > idx + i && is_hex(orig_buf + idx + i)) { + if ((i % 2)) { - fromhex += 2; + if (len > idx + i && is_hex(orig_buf + idx + i)) { - if (!from_up) { + fromhex += 2; - if (orig_buf[idx + i] >= 'A' && orig_buf[idx + i] <= 'F') - from_up = 1; - else if (orig_buf[idx + i] >= 'a' && orig_buf[idx + i] <= 'f') - from_up = 2; - if (orig_buf[idx + i - 1] >= 'A' && orig_buf[idx + i - 1] <= 'F') - from_up = 1; - else if (orig_buf[idx + i - 1] >= 'a' && - orig_buf[idx + i - 1] <= 'f') - from_up = 2; + if (!from_up) { - } + if (orig_buf[idx + i] >= 'A' && orig_buf[idx + i] <= 'F') + from_up = 1; + else if (orig_buf[idx + i] >= 'a' && orig_buf[idx + i] <= 'f') + from_up = 2; + if (orig_buf[idx + i - 1] >= 'A' && orig_buf[idx + i - 1] <= 'F') + from_up = 1; + else if (orig_buf[idx + i - 1] >= 'a' && + orig_buf[idx + i - 1] <= 'f') + from_up = 2; } } - if (i % 3 == 2 && i + to_lf + to_cr < 24) { + } - if (is_base64(repl + i + to_lf + to_cr)) tob64 += 3; + if (i % 3 == 2 && i < 24) { - } + if (is_base64(repl + ((i / 3) << 2))) tob64 += 3; - if (i % 4 == 3 && i < 24) { + } - if (is_base64(orig_buf + idx + i)) fromb64 += 4; + if (i % 4 == 3 && i < 24) { - } + if (is_base64(orig_buf + idx + i - 3)) fromb64 += 4; } @@ -1943,18 +1932,17 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } #ifdef _DEBUG - fprintf( - stderr, - "RTN loop=%u xor=%u arith=%u tolower=%u toupper=%u tohex=%u tob64=%u " - "fromhex=%u fromb64=%u to_0=%u to_slash=%u to_x=%u to_lf=%u to_cr=%u " - "from_0=%u from_slash=%u from_x=%u from_lf=%u from_cr=%u\n", - i, xor, arith, tolower, toupper, tohex, tob64, fromhex, fromb64, to_0, - to_slash, to_x, to_lf, to_cr, from_0, from_slash, from_x, from_lf, - from_cr); + fprintf(stderr, + "RTN idx=%u loop=%u xor=%u arith=%u tolower=%u toupper=%u " + "tohex=%u tob64=%u " + "fromhex=%u fromb64=%u to_0=%u to_slash=%u to_x=%u " + "from_0=%u from_slash=%u from_x=%u\n", + idx, i, xor, arith, tolower, toupper, tohex, tob64, fromhex, + fromb64, to_0, to_slash, to_x, from_0, from_slash, from_x); #endif // input is base64 and converted to binary? convert repl to base64! - if (i && !(i % 4) && i < 24 && fromb64 > i) { + if ((i % 4) == 3 && i < 24 && fromb64 > i) { to_base64(repl, tmp, i + 1); memcpy(buf + idx, tmp, i + 1); @@ -1965,12 +1953,13 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } // input is converted to base64? decode repl with base64! - if (i && !(i % 3) && i < 24 && tob64 > i) { + if ((i % 3) == 2 && i < 24 && tob64 > i) { u32 olen = from_base64(repl, tmp, i + 1); memcpy(buf + idx, tmp, olen); if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } - // fprintf(stderr, "RTN ATTEMPT tob64 %u result %u\n", tob64, *status); + // fprintf(stderr, "RTN ATTEMPT tob64 %u idx=%u result %u\n", tob64, + // idx, *status); } -- cgit v1.2.3 From ba47bee25207436db8e2b98ef2d02801967980ca Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 21 Jan 2021 11:41:25 +0100 Subject: pre merge changes --- src/afl-fuzz-redqueen.c | 57 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 8ffd39da..d631332a 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -29,10 +29,11 @@ #include "cmplog.h" //#define _DEBUG -#define COMBINE +//#define COMBINE //#define CMPLOG_INTROSPECTION //#define ARITHMETIC_LESSER_GREATER -#define TRANSFORM +//#define TRANSFORM +//#define TRANSFORM_BASE64 // CMP attribute enum enum { @@ -51,9 +52,9 @@ enum { // CMPLOG LVL enum { - LVL1 = 1, - LVL2 = 2, - LVL3 = 4 + LVL1 = 1, // Integer solving + LVL2 = 2, // FP solving + LVL3 = 4 // expensive tranformations }; @@ -238,6 +239,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 start_time = get_cur_time(); #endif + u32 screen_update = 1000000 / afl->queue_cur->exec_us; u64 orig_hit_cnt, new_hit_cnt, exec_cksum; orig_hit_cnt = afl->queued_paths + afl->unique_crashes; @@ -315,7 +317,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, } - ++afl->stage_cur; + if (++afl->stage_cur % screen_update) { show_stats(afl); }; } @@ -550,6 +552,7 @@ static int is_hex(const char *str) { } + #ifdef TRANSFORM_BASE64 // tests 4 bytes at location static int is_base64(const char *str) { @@ -662,6 +665,8 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) { } + #endif + #endif static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, @@ -1728,6 +1733,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } memcpy(save, &buf[saved_idx - to], its_len + to); + (void)(j); #ifdef _DEBUG fprintf(stderr, "RTN T idx=%u lvl=%02x ", idx, lvl); @@ -1796,8 +1802,10 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, if (lvl & LVL3) { - u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, tob64 = 0; - u32 fromhex = 0, fromb64 = 0; + u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, fromhex = 0; + #ifdef TRANSFORM_BASE64 + u32 tob64 = 0, fromb64 = 0; + #endif 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]; @@ -1893,6 +1901,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } + #ifdef TRANSFORM_BASE64 if (i % 3 == 2 && i < 24) { if (is_base64(repl + ((i / 3) << 2))) tob64 += 3; @@ -1905,6 +1914,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } + #endif + if ((o_pattern[i] ^ orig_buf[idx + i]) == xor_val[i] && xor_val[i]) { ++xor; @@ -1934,13 +1945,17 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, #ifdef _DEBUG fprintf(stderr, "RTN idx=%u loop=%u xor=%u arith=%u tolower=%u toupper=%u " - "tohex=%u tob64=%u " - "fromhex=%u fromb64=%u to_0=%u to_slash=%u to_x=%u " + "tohex=%u fromhex=%u to_0=%u to_slash=%u to_x=%u " "from_0=%u from_slash=%u from_x=%u\n", - idx, i, xor, arith, tolower, toupper, tohex, tob64, fromhex, - fromb64, to_0, to_slash, to_x, from_0, from_slash, from_x); + idx, i, xor, arith, tolower, toupper, tohex, fromhex, to_0, + to_slash, to_x, from_0, from_slash, from_x); + #ifdef TRANSFORM_BASE64 + fprintf(stderr, "RTN idx=%u loop=%u tob64=%u from64=%u\n", tob64, + fromb64); + #endif #endif + #ifdef TRANSFORM_BASE64 // input is base64 and converted to binary? convert repl to base64! if ((i % 4) == 3 && i < 24 && fromb64 > i) { @@ -1963,6 +1978,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } + #endif + // input is converted to hex? convert repl to binary! if (i < 16 && tohex > i) { @@ -2096,8 +2113,11 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, if ((i >= 7 && (i >= xor&&i >= arith &&i >= tolower &&i >= toupper &&i > tohex &&i > - (1 + fromhex + from_0 + from_x + from_slash) && - i > tob64 + 3 && i > fromb64 + 3)) || + (fromhex + from_0 + from_x + from_slash + 1) + #ifdef TRANSFORM_BASE64 + && i > tob64 + 3 && i > fromb64 + 4 + #endif + )) || repl[i] != changed_val[i] || *status == 1) { break; @@ -2348,6 +2368,8 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { u64 orig_hit_cnt, new_hit_cnt; u64 orig_execs = afl->fsrv.total_execs; orig_hit_cnt = afl->queued_paths + afl->unique_crashes; + u64 screen_update = 1000000 / afl->queue_cur->exec_us, + execs = afl->fsrv.total_execs; afl->stage_name = "input-to-state"; afl->stage_short = "its"; @@ -2440,6 +2462,13 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } + if (afl->fsrv.total_execs - execs > screen_update) { + + execs = afl->fsrv.total_execs; + show_stats(afl); + + } + } r = 0; -- cgit v1.2.3 From 0d472adef0cbe68cec128b7b15e508f0bb05455d Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 21 Jan 2021 12:02:50 +0100 Subject: temp conflict resolve --- src/afl-cc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index d44f069a..2ce986c7 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -856,8 +856,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_OFF()=__afl_coverage_off()"; cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_DISCARD()=__afl_coverage_discard()"; - cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_ABORT()=__afl_coverage_abort()"; - + cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_SKIP()=__afl_coverage_skip()"; cc_params[cc_par_cnt++] = "-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : " "__afl_fuzz_alt_ptr)"; -- cgit v1.2.3 From e8c1b43a3de7ae3d173c749c3be4e58a95d3372b Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 21 Jan 2021 15:24:34 +0100 Subject: fix docs --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 95bc0694..9a8159bd 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -123,7 +123,7 @@ static void usage(u8 *argv0, int more_help) { "it.\n" " if using QEMU, just use -c 0.\n" " -l cmplog_level - set the complexity/intensivity of CmpLog.\n" - " Values: 1 (default), 2 (intensive) and 3 (heavy)\n\n" + " Values: 1 (integer+string), 2 (+FP) and 3 (+transform)\n\n" "Fuzzing behavior settings:\n" " -Z - sequential queue selection instead of weighted " -- cgit v1.2.3 From b850951c726258053c5635d6597704cf346fe3c4 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 21 Jan 2021 17:15:14 +0100 Subject: code format and not setting sanitizers if debug and settings present --- src/afl-cc.c | 8 ++++---- src/afl-forkserver.c | 53 +++++++++++++++++++++++++++------------------------ src/afl-fuzz-bitmap.c | 6 +----- src/afl-fuzz-stats.c | 2 ++ src/afl-fuzz.c | 12 ++++++++---- src/afl-ld-lto.c | 2 +- 6 files changed, 44 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index b0b11f48..8e7af0f9 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -586,9 +586,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (instrument_mode == INSTRUMENT_PCGUARD) { #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) -#ifdef __ANDROID__ + #ifdef __ANDROID__ cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; -#else + #else if (have_instr_list) { if (!be_quiet) @@ -608,7 +608,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } -#endif + #endif #else #if LLVM_MAJOR >= 4 if (!be_quiet) @@ -1036,7 +1036,7 @@ int main(int argc, char **argv, char **envp) { #endif #ifdef __ANDROID__ - have_llvm = 1; + have_llvm = 1; #endif if ((ptr = find_object("afl-gcc-pass.so", argv[0])) != NULL) { diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 50e4139b..d4484de7 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -484,38 +484,41 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, /* Set sane defaults for ASAN if nothing else specified. */ - setenv("ASAN_OPTIONS", - "abort_on_error=1:" - "detect_leaks=0:" - "malloc_context_size=0:" - "symbolize=0:" - "allocator_may_return_null=1:" - "handle_segv=0:" - "handle_sigbus=0:" - "handle_abort=0:" - "handle_sigfpe=0:" - "handle_sigill=0", - 0); + if (!afl->debug || !getenv("ASAN_OPTIONS")) + setenv("ASAN_OPTIONS", + "abort_on_error=1:" + "detect_leaks=0:" + "malloc_context_size=0:" + "symbolize=0:" + "allocator_may_return_null=1:" + "handle_segv=0:" + "handle_sigbus=0:" + "handle_abort=0:" + "handle_sigfpe=0:" + "handle_sigill=0", + 0); /* Set sane defaults for UBSAN if nothing else specified. */ - setenv("UBSAN_OPTIONS", - "halt_on_error=1:" - "abort_on_error=1:" - "malloc_context_size=0:" - "allocator_may_return_null=1:" - "symbolize=0:" - "handle_segv=0:" - "handle_sigbus=0:" - "handle_abort=0:" - "handle_sigfpe=0:" - "handle_sigill=0", - 0); + if (!afl->debug || !getenv("UBSAN_OPTIONS")) + setenv("UBSAN_OPTIONS", + "halt_on_error=1:" + "abort_on_error=1:" + "malloc_context_size=0:" + "allocator_may_return_null=1:" + "symbolize=0:" + "handle_segv=0:" + "handle_sigbus=0:" + "handle_abort=0:" + "handle_sigfpe=0:" + "handle_sigill=0", + 0); /* MSAN is tricky, because it doesn't support abort_on_error=1 at this point. So, we do this in a very hacky way. */ - setenv("MSAN_OPTIONS", + if (!afl->debug || !getenv("MSAN_OPTIONS")) + setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":" "symbolize=0:" "abort_on_error=1:" diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 586f3990..0c4a114e 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -700,11 +700,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (likely(!afl->non_instrumented_mode)) { - if (!classified) { - - classify_counts(&afl->fsrv); - - } + if (!classified) { classify_counts(&afl->fsrv); } simplify_trace(afl, afl->fsrv.trace_bits); diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index e67bace9..82da8176 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -60,8 +60,10 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { if (i) fprintf(f, " "); #ifdef __ANDROID__ if (memchr(argv[i], '\'', sizeof(argv[i]))) { + #else if (index(argv[i], '\'')) { + #endif fprintf(f, "'"); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 9a8159bd..2a59bbe4 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -123,7 +123,8 @@ static void usage(u8 *argv0, int more_help) { "it.\n" " if using QEMU, just use -c 0.\n" " -l cmplog_level - set the complexity/intensivity of CmpLog.\n" - " Values: 1 (integer+string), 2 (+FP) and 3 (+transform)\n\n" + " Values: 1 (integer+string), 2 (+FP) and 3 " + "(+transform)\n\n" "Fuzzing behavior settings:\n" " -Z - sequential queue selection instead of weighted " @@ -584,7 +585,8 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->timeout_given) { FATAL("Multiple -t options not supported"); } - if (!optarg || sscanf(optarg, "%u%c", &afl->fsrv.exec_tmout, &suffix) < 1 || + if (!optarg || + sscanf(optarg, "%u%c", &afl->fsrv.exec_tmout, &suffix) < 1 || optarg[0] == '-') { FATAL("Bad syntax used for -t"); @@ -766,7 +768,8 @@ int main(int argc, char **argv_orig, char **envp) { case 'V': { afl->most_time_key = 1; - if (!optarg || sscanf(optarg, "%llu", &afl->most_time) < 1 || optarg[0] == '-') { + if (!optarg || sscanf(optarg, "%llu", &afl->most_time) < 1 || + optarg[0] == '-') { FATAL("Bad syntax used for -V"); @@ -777,7 +780,8 @@ int main(int argc, char **argv_orig, char **envp) { case 'E': { afl->most_execs_key = 1; - if (!optarg || sscanf(optarg, "%llu", &afl->most_execs) < 1 || optarg[0] == '-') { + if (!optarg || sscanf(optarg, "%llu", &afl->most_execs) < 1 || + optarg[0] == '-') { FATAL("Bad syntax used for -E"); diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index 0671d1c4..49c04e4a 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -252,7 +252,7 @@ static void edit_params(int argc, char **argv) { int main(int argc, char **argv) { - s32 pid, i, status; + s32 pid, i, status; char thecwd[PATH_MAX]; if (getenv("AFL_LD_CALLER") != NULL) { -- cgit v1.2.3 From 040bf5a61db5fa939c6e2a884207f18b62bf1522 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 21 Jan 2021 18:26:08 +0100 Subject: fix silly mistake --- src/afl-forkserver.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index d4484de7..4ee88216 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -484,7 +484,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, /* Set sane defaults for ASAN if nothing else specified. */ - if (!afl->debug || !getenv("ASAN_OPTIONS")) + if (!getenv("ASAN_OPTIONS")) setenv("ASAN_OPTIONS", "abort_on_error=1:" "detect_leaks=0:" @@ -500,7 +500,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, /* Set sane defaults for UBSAN if nothing else specified. */ - if (!afl->debug || !getenv("UBSAN_OPTIONS")) + if (!getenv("UBSAN_OPTIONS")) setenv("UBSAN_OPTIONS", "halt_on_error=1:" "abort_on_error=1:" @@ -517,7 +517,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, /* MSAN is tricky, because it doesn't support abort_on_error=1 at this point. So, we do this in a very hacky way. */ - if (!afl->debug || !getenv("MSAN_OPTIONS")) + if (!getenv("MSAN_OPTIONS")) setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":" "symbolize=0:" -- cgit v1.2.3 From 60764ebdf15be0affdd3040135fc6eb36e10d677 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 21 Jan 2021 18:43:06 +0100 Subject: forkserver debug flag support --- src/afl-forkserver.c | 9 +++++---- src/afl-fuzz.c | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 4ee88216..1f5685b0 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -91,7 +91,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) { fsrv->map_size = get_map_size(); fsrv->use_fauxsrv = false; fsrv->last_run_timed_out = false; - + fsrv->debug = false; fsrv->uses_crash_exitcode = false; fsrv->uses_asan = false; @@ -117,6 +117,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->uses_crash_exitcode = from->uses_crash_exitcode; fsrv_to->crash_exitcode = from->crash_exitcode; fsrv_to->kill_signal = from->kill_signal; + fsrv_to->debug = from->debug; // These are forkserver specific. fsrv_to->out_dir_fd = -1; @@ -484,7 +485,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, /* Set sane defaults for ASAN if nothing else specified. */ - if (!getenv("ASAN_OPTIONS")) + if (fsrv->debug == true && !getenv("ASAN_OPTIONS")) setenv("ASAN_OPTIONS", "abort_on_error=1:" "detect_leaks=0:" @@ -500,7 +501,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, /* Set sane defaults for UBSAN if nothing else specified. */ - if (!getenv("UBSAN_OPTIONS")) + if (fsrv->debug == true && !getenv("UBSAN_OPTIONS")) setenv("UBSAN_OPTIONS", "halt_on_error=1:" "abort_on_error=1:" @@ -517,7 +518,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, /* MSAN is tricky, because it doesn't support abort_on_error=1 at this point. So, we do this in a very hacky way. */ - if (!getenv("MSAN_OPTIONS")) + if (fsrv->debug == true && !getenv("MSAN_OPTIONS")) setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":" "symbolize=0:" diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 2a59bbe4..9b62e961 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -339,6 +339,7 @@ int main(int argc, char **argv_orig, char **envp) { afl_state_init(afl, map_size); afl->debug = debug; afl_fsrv_init(&afl->fsrv); + if (debug) { afl->fsrv.debug = true ; } read_afl_environment(afl, envp); if (afl->shm.map_size) { afl->fsrv.map_size = afl->shm.map_size; } -- cgit v1.2.3 From 30148bc1a9938cc29047d198eab72818cd037e3c Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 21 Jan 2021 19:58:25 +0100 Subject: fix afl-showmap and gcc plugin test --- src/afl-showmap.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index ee6d6de9..ab47c602 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -85,6 +85,7 @@ static u8 quiet_mode, /* Hide non-essential messages? */ keep_cores, /* Allow coredumps? */ remove_shm = 1, /* remove shmem? */ collect_coverage, /* collect coverage */ + have_coverage, /* have coverage? */ no_classify; /* do not classify counts */ static volatile u8 stop_soon, /* Ctrl-C pressed? */ @@ -316,7 +317,8 @@ static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, u8 *mem, } - if (fsrv->trace_bits[0] == 1) { fsrv->trace_bits[0] = 0; } + if (fsrv->trace_bits[0] == 1) { fsrv->trace_bits[0] = 0; have_coverage = 1; } + else { have_coverage = 0; } if (!no_classify) { classify_counts(fsrv); } @@ -491,7 +493,8 @@ static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) { } - if (fsrv->trace_bits[0] == 1) { fsrv->trace_bits[0] = 0; } + if (fsrv->trace_bits[0] == 1) { fsrv->trace_bits[0] = 0; have_coverage = 1; } + else { have_coverage = 0; } if (!no_classify) { classify_counts(fsrv); } @@ -1232,7 +1235,7 @@ int main(int argc, char **argv_orig, char **envp) { if (!quiet_mode || collect_coverage) { - if (!tcnt) { FATAL("No instrumentation detected" cRST); } + if (!tcnt && !have_coverage) { FATAL("No instrumentation detected" cRST); } OKF("Captured %u tuples (highest value %u, total values %llu) in " "'%s'." cRST, tcnt, highest, total, out_file); -- cgit v1.2.3 From 258ae1632af49d9ee68b1ce1a6c74d9e92245bcf Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 22 Jan 2021 21:10:23 +0100 Subject: stack 2 heap --- src/afl-fuzz-init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index cbff6d7e..b1a24f2f 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -810,7 +810,7 @@ void perform_dry_run(afl_state_t *afl) { while (q) { - u8 use_mem[MAX_FILE]; + u8 *use_mem = afl_realloc(AFL_BUF_PARAM(in), MAX_FILE); u8 res; s32 fd; -- cgit v1.2.3 From 0a3a708f9bf7b9f192d236c792a13cec2aa54a16 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 23 Jan 2021 10:01:09 +0100 Subject: less stack mem req --- src/afl-fuzz-init.c | 3 ++- src/afl-fuzz-queue.c | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index b1a24f2f..fed58eb6 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -807,10 +807,10 @@ void perform_dry_run(afl_state_t *afl) { struct queue_entry *q = afl->queue; u32 cal_failures = 0; u8 * skip_crashes = afl->afl_env.afl_skip_crashes; + u8 * use_mem; while (q) { - u8 *use_mem = afl_realloc(AFL_BUF_PARAM(in), MAX_FILE); u8 res; s32 fd; @@ -829,6 +829,7 @@ void perform_dry_run(afl_state_t *afl) { if (fd < 0) { PFATAL("Unable to open '%s'", q->fname); } u32 read_len = MIN(q->len, (u32)MAX_FILE); + use_mem = afl_realloc(AFL_BUF_PARAM(in), read_len); if (read(fd, use_mem, read_len) != (ssize_t)read_len) { FATAL("Short read from '%s'", q->fname); diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index aec57a6e..90f969d9 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -313,17 +313,18 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) { /* check if ascii or UTF-8 */ -static u8 check_if_text(struct queue_entry *q) { +static u8 check_if_text(afl_state_t *afl, struct queue_entry *q) { if (q->len < AFL_TXT_MIN_LEN) return 0; - u8 buf[MAX_FILE]; + u8 *buf; int fd; u32 len = q->len, offset = 0, ascii = 0, utf8 = 0; ssize_t comp; if (len >= MAX_FILE) len = MAX_FILE - 1; if ((fd = open(q->fname, O_RDONLY)) < 0) return 0; + buf = afl_realloc(AFL_BUF_PARAM(in_scratch), len); comp = read(fd, buf, len); close(fd); if (comp != (ssize_t)len) return 0; @@ -487,7 +488,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { } /* only redqueen currently uses is_ascii */ - if (afl->shm.cmplog_mode) q->is_ascii = check_if_text(q); + if (afl->shm.cmplog_mode) q->is_ascii = check_if_text(afl, q); } -- cgit v1.2.3 From cd8668ad3ace7d5e369d492197a7da787183c056 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 25 Jan 2021 13:55:09 +0100 Subject: mopt fix --- src/afl-fuzz-one.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 4ce22c08..a7262eec 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -4781,8 +4781,7 @@ pacemaker_fuzzing: } - afl->stage_cycles_puppet_v2[afl->swarm_now] - [STAGE_OverWriteExtra]++; + MOpt_globals.cycles_v2[STAGE_OverWriteExtra]++; break; @@ -4837,8 +4836,7 @@ pacemaker_fuzzing: memcpy(out_buf + insert_at, ptr, extra_len); temp_len += extra_len; - afl->stage_cycles_puppet_v2[afl->swarm_now][STAGE_InsertExtra] += - 1; + MOpt_globals.cycles_v2[STAGE_InsertExtra]++; break; } @@ -4920,7 +4918,7 @@ pacemaker_fuzzing: } - afl->stage_cycles_puppet_v2[afl->swarm_now][STAGE_Splice]++; + MOpt_globals.cycles_v2[STAGE_Splice]++; break; } // end of default: -- cgit v1.2.3 From 7c381a782e3bb05335df745ea6130c0a668463da Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 25 Jan 2021 20:18:42 +0100 Subject: enable cmplog combine --- src/afl-fuzz-redqueen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index d631332a..6721b8ef 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -29,7 +29,7 @@ #include "cmplog.h" //#define _DEBUG -//#define COMBINE +#define COMBINE //#define CMPLOG_INTROSPECTION //#define ARITHMETIC_LESSER_GREATER //#define TRANSFORM -- cgit v1.2.3 From e0663c91b9cbf1bdc46593dec4ba11224e6847d7 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 26 Jan 2021 12:15:13 +0100 Subject: wip fix --- src/afl-fuzz-init.c | 23 ++++++++++++++++++----- src/afl-fuzz-one.c | 13 +++++++++---- 2 files changed, 27 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index fed58eb6..2cb152a9 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1026,6 +1026,14 @@ void perform_dry_run(afl_state_t *afl) { /* Remove from fuzzing queue but keep for splicing */ struct queue_entry *p = afl->queue; + + if (!p->disabled && !p->was_fuzzed) { + + --afl->pending_not_fuzzed; + --afl->active_paths; + + } + p->disabled = 1; p->perf_score = 0; while (p && p->next != q) @@ -1036,9 +1044,6 @@ void perform_dry_run(afl_state_t *afl) { else afl->queue = q->next; - --afl->pending_not_fuzzed; - --afl->active_paths; - afl->max_depth = 0; p = afl->queue; while (p) { @@ -1123,8 +1128,16 @@ restart_outer_cull_loop: if (!p->cal_failed && p->exec_cksum == q->exec_cksum) { duplicates = 1; - --afl->pending_not_fuzzed; - afl->active_paths--; + if (!p->disabled && !q->disabled && !p->was_fuzzed && !q->was_fuzzed) { + + --afl->pending_not_fuzzed; + afl->active_paths--; + + } else { + + FATAL("disabled entry? this should not happen, please report!"); + + } // We do not remove any of the memory allocated because for // splicing the data might still be interesting. diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index a7262eec..af768183 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2782,11 +2782,16 @@ abandon_entry: cycle and have not seen this entry before. */ if (!afl->stop_soon && !afl->queue_cur->cal_failed && - (afl->queue_cur->was_fuzzed == 0 || afl->queue_cur->fuzz_level == 0)) { + (afl->queue_cur->was_fuzzed == 0 || afl->queue_cur->fuzz_level == 0) && + !afl->queue_cur->disabled) { - --afl->pending_not_fuzzed; - afl->queue_cur->was_fuzzed = 1; - if (afl->queue_cur->favored) { --afl->pending_favored; } + if (!afl->queue_cur->was_fuzzed) { + + --afl->pending_not_fuzzed; + afl->queue_cur->was_fuzzed = 1; + if (afl->queue_cur->favored) { --afl->pending_favored; } + + } } -- cgit v1.2.3 From 9c393adbb953fe5bf6809e5b0feca7be2f52b7f8 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 26 Jan 2021 17:12:11 +0100 Subject: real fix plus code format --- src/afl-fuzz-init.c | 28 +++++++++++++++++----------- src/afl-fuzz-queue.c | 2 +- src/afl-fuzz.c | 2 +- src/afl-showmap.c | 24 ++++++++++++++++++++---- 4 files changed, 39 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 2cb152a9..ed2010cd 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1027,7 +1027,7 @@ void perform_dry_run(afl_state_t *afl) { struct queue_entry *p = afl->queue; - if (!p->disabled && !p->was_fuzzed) { + if (!p->was_fuzzed) { --afl->pending_not_fuzzed; --afl->active_paths; @@ -1128,16 +1128,6 @@ restart_outer_cull_loop: if (!p->cal_failed && p->exec_cksum == q->exec_cksum) { duplicates = 1; - if (!p->disabled && !q->disabled && !p->was_fuzzed && !q->was_fuzzed) { - - --afl->pending_not_fuzzed; - afl->active_paths--; - - } else { - - FATAL("disabled entry? this should not happen, please report!"); - - } // We do not remove any of the memory allocated because for // splicing the data might still be interesting. @@ -1147,6 +1137,14 @@ restart_outer_cull_loop: // we keep the shorter file if (p->len >= q->len) { + if (!p->was_fuzzed) { + + p->was_fuzzed = 1; + --afl->pending_not_fuzzed; + afl->active_paths--; + + } + p->disabled = 1; p->perf_score = 0; q->next = p->next; @@ -1154,6 +1152,14 @@ restart_outer_cull_loop: } else { + if (!q->was_fuzzed) { + + q->was_fuzzed = 1; + --afl->pending_not_fuzzed; + afl->active_paths--; + + } + q->disabled = 1; q->perf_score = 0; if (prev) diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 90f969d9..4442b400 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -317,7 +317,7 @@ static u8 check_if_text(afl_state_t *afl, struct queue_entry *q) { if (q->len < AFL_TXT_MIN_LEN) return 0; - u8 *buf; + u8 * buf; int fd; u32 len = q->len, offset = 0, ascii = 0, utf8 = 0; ssize_t comp; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 9b62e961..ecf69728 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -339,7 +339,7 @@ int main(int argc, char **argv_orig, char **envp) { afl_state_init(afl, map_size); afl->debug = debug; afl_fsrv_init(&afl->fsrv); - if (debug) { afl->fsrv.debug = true ; } + if (debug) { afl->fsrv.debug = true; } read_afl_environment(afl, envp); if (afl->shm.map_size) { afl->fsrv.map_size = afl->shm.map_size; } diff --git a/src/afl-showmap.c b/src/afl-showmap.c index ab47c602..5a0b6ecf 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -317,8 +317,16 @@ static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, u8 *mem, } - if (fsrv->trace_bits[0] == 1) { fsrv->trace_bits[0] = 0; have_coverage = 1; } - else { have_coverage = 0; } + if (fsrv->trace_bits[0] == 1) { + + fsrv->trace_bits[0] = 0; + have_coverage = 1; + + } else { + + have_coverage = 0; + + } if (!no_classify) { classify_counts(fsrv); } @@ -493,8 +501,16 @@ static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) { } - if (fsrv->trace_bits[0] == 1) { fsrv->trace_bits[0] = 0; have_coverage = 1; } - else { have_coverage = 0; } + if (fsrv->trace_bits[0] == 1) { + + fsrv->trace_bits[0] = 0; + have_coverage = 1; + + } else { + + have_coverage = 0; + + } if (!no_classify) { classify_counts(fsrv); } -- cgit v1.2.3 From 36b5336152cd886d911f4299c3154b7817c94838 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 26 Jan 2021 22:45:59 +0100 Subject: better foreign sync name --- src/afl-fuzz-init.c | 15 ++++++++++++++- src/afl-fuzz-redqueen.c | 4 ++-- src/afl-fuzz.c | 10 ++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index ed2010cd..4f59a42f 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -460,6 +460,7 @@ void read_foreign_testcases(afl_state_t *afl, int first) { u32 i, iter; u8 val_buf[2][STRINGIFY_VAL_SIZE_MAX]; + u8 foreign_name[16]; for (iter = 0; iter < afl->foreign_sync_cnt; iter++) { @@ -468,6 +469,18 @@ void read_foreign_testcases(afl_state_t *afl, int first) { if (first) ACTF("Scanning '%s'...", afl->foreign_syncs[iter].dir); time_t ctime_max = 0; + u8 * name = rindex(afl->foreign_syncs[iter].dir, '/'); + if (!name) { name = afl->foreign_syncs[iter].dir; } + if (!strcmp(name, "queue") || !strcmp(name, "out") || + !strcmp(name, "default")) { + + snprintf(foreign_name, sizeof(foreign_name), "foreign_%u", iter); + + } else { + + snprintf(foreign_name, sizeof(foreign_name), "%s_%u", name, iter); + + } /* We use scandir() + alphasort() rather than readdir() because otherwise, the ordering of test cases would vary somewhat randomly and would be @@ -581,7 +594,7 @@ void read_foreign_testcases(afl_state_t *afl, int first) { write_to_testcase(afl, mem, st.st_size); fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); - afl->syncing_party = "foreign"; + afl->syncing_party = foreign_name; afl->queued_imported += save_if_interesting(afl, mem, st.st_size, fault); afl->syncing_party = 0; diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 6721b8ef..34db7231 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -249,7 +249,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, afl->stage_cur = 0; // in colorization we do not classify counts, hence we have to calculate - // the original checksum! + // the original checksum. if (unlikely(get_exec_checksum(afl, buf, len, &exec_cksum))) { goto checksum_fail; @@ -2368,7 +2368,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { u64 orig_hit_cnt, new_hit_cnt; u64 orig_execs = afl->fsrv.total_execs; orig_hit_cnt = afl->queued_paths + afl->unique_crashes; - u64 screen_update = 1000000 / afl->queue_cur->exec_us, + u64 screen_update = 100000 / afl->queue_cur->exec_us, execs = afl->fsrv.total_execs; afl->stage_name = "input-to-state"; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index ecf69728..b92aa2a7 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -559,6 +559,16 @@ int main(int argc, char **argv_orig, char **envp) { FATAL("Maximum %u entried of -F option can be specified", FOREIGN_SYNCS_MAX); afl->foreign_syncs[afl->foreign_sync_cnt].dir = optarg; + while (afl->foreign_syncs[afl->foreign_sync_cnt] + .dir[strlen(afl->foreign_syncs[afl->foreign_sync_cnt].dir) - + 1] == '/') { + + afl->foreign_syncs[afl->foreign_sync_cnt] + .dir[strlen(afl->foreign_syncs[afl->foreign_sync_cnt].dir) - 1] = + 0; + + } + afl->foreign_sync_cnt++; break; -- cgit v1.2.3 From a754694ac4fa7b4016fb9de3253b0f3fe691fdf1 Mon Sep 17 00:00:00 2001 From: fuzzah <60884276+fuzzah@users.noreply.github.com> Date: Wed, 27 Jan 2021 05:48:59 +0300 Subject: include limits.h to fix build on BSD systems --- src/afl-ld-lto.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index 49c04e4a..1fb01600 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -45,6 +45,11 @@ #include +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \ + defined(__DragonFly__) + #include +#endif + #ifdef __APPLE__ #include #endif -- cgit v1.2.3 From d046b28f2fb5981ce4a28ddcfac6ec3405624450 Mon Sep 17 00:00:00 2001 From: Adrian Panasiuk <4141848+ampanasiuk@users.noreply.github.com> Date: Wed, 27 Jan 2021 01:12:13 +0000 Subject: Fix "src" attribute in sync stage filenames (#703) --- src/afl-fuzz-run.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 17c305ed..97cb7415 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -627,9 +627,8 @@ void sync_fuzzers(afl_state_t *afl) { } if (m >= n) { goto close_sync; } // nothing new - o = n - 1; - while (o >= m) { + for (o = m; o < n; o++) { s32 fd; struct stat st; @@ -637,7 +636,6 @@ void sync_fuzzers(afl_state_t *afl) { snprintf(path, sizeof(path), "%s/%s", qd_path, namelist[o]->d_name); afl->syncing_case = next_min_accept; next_min_accept++; - o--; /* Allow this to fail in case the other fuzzer is resuming or so... */ -- cgit v1.2.3 From 2044c7e2b548e2747fde5deff65c78dd05e2ec8d Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 27 Jan 2021 08:41:45 +0100 Subject: fix include --- src/afl-fuzz-init.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 4f59a42f..a428923d 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -482,9 +482,8 @@ void read_foreign_testcases(afl_state_t *afl, int first) { } - /* We use scandir() + alphasort() rather than readdir() because otherwise, - the ordering of test cases would vary somewhat randomly and would be - difficult to control. */ + /* We do not use sorting yet and do a more expensive ctime check instead. + a ctimesort() implementation would be better though. */ nl_cnt = scandir(afl->foreign_syncs[iter].dir, &nl, NULL, NULL); -- cgit v1.2.3 From 47f62eb0ca087bf26e79f2f0ce5935eda2599064 Mon Sep 17 00:00:00 2001 From: Joey Jiaojg <77719320+joeyjiaojg@users.noreply.github.com> Date: Thu, 28 Jan 2021 12:51:45 +0800 Subject: Fix dev branch for android (#710) * android: replace rindex with strrchr * android: support 64bit only due to 128bit integer not supported by 32bit system Co-authored-by: joeyjiaojg@qq.com --- src/afl-fuzz-init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index a428923d..5f5e65cd 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -469,7 +469,7 @@ void read_foreign_testcases(afl_state_t *afl, int first) { if (first) ACTF("Scanning '%s'...", afl->foreign_syncs[iter].dir); time_t ctime_max = 0; - u8 * name = rindex(afl->foreign_syncs[iter].dir, '/'); + u8 * name = strrchr(afl->foreign_syncs[iter].dir, '/'); if (!name) { name = afl->foreign_syncs[iter].dir; } if (!strcmp(name, "queue") || !strcmp(name, "out") || !strcmp(name, "default")) { -- cgit v1.2.3 From ad63ba49c181dd97786745913c6b2ade5ae69728 Mon Sep 17 00:00:00 2001 From: Yuan Date: Thu, 28 Jan 2021 17:21:54 +0800 Subject: Fix getopt arg string There is no '-P' case here. --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index b92aa2a7..a1f749b5 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -357,7 +357,7 @@ int main(int argc, char **argv_orig, char **envp) { while ((opt = getopt( argc, argv, - "+b:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNo:p:P:RQs:S:t:T:UV:Wx:Z")) > + "+b:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNo:p:RQs:S:t:T:UV:Wx:Z")) > 0) { switch (opt) { -- cgit v1.2.3 From a61a30dee03aced16d117150c4dbfd7079de7e68 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 28 Jan 2021 14:11:33 +0100 Subject: fix another pending_not_fuzzed location --- src/afl-fuzz-extras.c | 2 +- src/afl-fuzz-init.c | 5 +++-- src/afl-fuzz-one.c | 4 ++-- src/afl-fuzz.c | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index a3583651..7ecad233 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -413,7 +413,7 @@ void dedup_extras(afl_state_t *afl) { if (j + 1 < afl->extras_cnt) // not at the end of the list? memmove((char *)&afl->extras[j], (char *)&afl->extras[j + 1], (afl->extras_cnt - j - 1) * sizeof(struct extra_data)); - afl->extras_cnt--; + --afl->extras_cnt; goto restart_dedup; // restart if several duplicates are in a row } diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 5f5e65cd..84f81112 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1041,6 +1041,7 @@ void perform_dry_run(afl_state_t *afl) { if (!p->was_fuzzed) { + p->was_fuzzed = 1; --afl->pending_not_fuzzed; --afl->active_paths; @@ -1153,7 +1154,7 @@ restart_outer_cull_loop: p->was_fuzzed = 1; --afl->pending_not_fuzzed; - afl->active_paths--; + --afl->active_paths; } @@ -1168,7 +1169,7 @@ restart_outer_cull_loop: q->was_fuzzed = 1; --afl->pending_not_fuzzed; - afl->active_paths--; + --afl->active_paths; } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index af768183..ff766158 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -530,7 +530,7 @@ u8 fuzz_one_original(afl_state_t *afl) { len = afl->queue_cur->len; /* maybe current entry is not ready for splicing anymore */ - if (unlikely(len <= 4 && old_len > 4)) afl->ready_for_splicing_count--; + if (unlikely(len <= 4 && old_len > 4)) --afl->ready_for_splicing_count; } @@ -2958,7 +2958,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { len = afl->queue_cur->len; /* maybe current entry is not ready for splicing anymore */ - if (unlikely(len <= 4 && old_len > 4)) afl->ready_for_splicing_count--; + if (unlikely(len <= 4 && old_len > 4)) --afl->ready_for_splicing_count; } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index a1f749b5..e856730e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1636,7 +1636,7 @@ int main(int argc, char **argv_orig, char **envp) { (afl->old_seed_selection && !afl->queue_cur))) { ++afl->queue_cycle; - runs_in_current_cycle = 0; + runs_in_current_cycle = (u32)-1; afl->cur_skipped_paths = 0; if (unlikely(afl->old_seed_selection)) { -- cgit v1.2.3 From 2a9fcd2a87bf11bc019c8d6be2b6eda77b772ee2 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 28 Jan 2021 18:01:27 +0100 Subject: warn on afl-gcc/afl-clang instrumentation --- src/afl-cc.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 8e7af0f9..ff0f3c07 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1788,6 +1788,15 @@ int main(int argc, char **argv, char **envp) { } + if (!be_quiet && (compiler_mode == GCC || compiler_mode == CLANG)) { + + WARNF( + "You are using outdated instrumentation, install LLVM and/or " + "gcc-plugin and use afl-clang-fast/afl-clang-lto/afl-gcc-fast " + "instead!"); + + } + if (debug) { DEBUGF("cd '%s';", getthecwd()); -- cgit v1.2.3 From ce673ccab3f2ca438f879c1d2e63988eb9737a35 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 28 Jan 2021 19:19:57 +0100 Subject: remove snapshot reference --- src/afl-cc.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index ff0f3c07..b5dcb632 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1438,34 +1438,34 @@ int main(int argc, char **argv, char **envp) { " CC=afl-cc CXX=afl-c++ meson\n\n"); SAYF( - " |---------------- FEATURES " - "---------------|\n" - "MODES: NCC PERSIST SNAP DICT LAF " + " |------------- FEATURES " + "-------------|\n" + "MODES: NCC PERSIST DICT LAF " "CMPLOG SELECT\n" " [LTO] llvm LTO: %s%s\n" - " PCGUARD DEFAULT yes yes yes yes yes yes " + " PCGUARD DEFAULT yes yes yes yes yes " " yes\n" - " CLASSIC yes yes yes yes yes yes " + " CLASSIC yes yes yes yes yes " " yes\n" " [LLVM] llvm: %s%s\n" - " PCGUARD %s yes yes yes module yes yes " + " PCGUARD %s yes yes module yes yes " "extern\n" - " CLASSIC %s no yes yes module yes yes " + " CLASSIC %s no yes module yes yes " "yes\n" " - NORMAL\n" " - CTX\n" " - NGRAM-{2-16}\n" - " INSTRIM no yes yes module yes yes " + " INSTRIM no yes module yes yes " " yes\n" " - NORMAL\n" " - CTX\n" " - NGRAM-{2-16}\n" " [GCC_PLUGIN] gcc plugin: %s%s\n" - " CLASSIC DEFAULT no yes yes no no no " - " yes\n" + " CLASSIC DEFAULT no yes no no no " + "yes\n" " [GCC/CLANG] simple gcc/clang: %s%s\n" - " CLASSIC DEFAULT no no no no no no " - " no\n\n", + " CLASSIC DEFAULT no no no no no " + "no\n\n", have_lto ? "AVAILABLE" : "unavailable!", compiler_mode == LTO ? " [SELECTED]" : "", have_llvm ? "AVAILABLE" : "unavailable!", @@ -1520,9 +1520,6 @@ int main(int argc, char **argv, char **envp) { " (instrumentation/README.lto.md)\n" " PERSIST: persistent mode support [code] (huge speed increase!)\n" " (instrumentation/README.persistent_mode.md)\n" - " SNAP: linux lkm snapshot module support [automatic] (speed " - "increase)\n" - " (https://github.com/AFLplusplus/AFL-Snapshot-LKM/)\n" " DICT: dictionary in the target [yes=automatic or llvm module " "pass]\n" " (instrumentation/README.lto.md + " -- cgit v1.2.3 From 6f5746d42878207b5d17af71317220932a42ebd7 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Fri, 29 Jan 2021 15:38:49 +0100 Subject: AFL_USE_QASAN --- src/afl-analyze.c | 25 ++++++++++++++++++++ src/afl-common.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/afl-forkserver.c | 4 ++++ src/afl-fuzz.c | 30 +++++++++++++++++++++--- src/afl-showmap.c | 25 ++++++++++++++++++++ src/afl-tmin.c | 25 ++++++++++++++++++++ 6 files changed, 170 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 0af489fe..28598ba0 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -1078,6 +1078,31 @@ int main(int argc, char **argv_orig, char **envp) { if (optind == argc || !in_file) { usage(argv[0]); } + if (qemu_mode && getenv("AFL_USE_QASAN")) { + + u8* preload = getenv("AFL_PRELOAD"); + u8* libqasan = get_libqasan_path(argv_orig[0]); + + if (!preload) { + + setenv("AFL_PRELOAD", libqasan, 0); + + } else { + + u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2); + strcpy(result, libqasan); + strcat(result, " "); + strcat(result, preload); + + setenv("AFL_PRELOAD", result, 1); + ck_free(result); + + } + + ck_free(libqasan); + + } + map_size = get_map_size(); use_hex_offsets = !!get_afl_env("AFL_ANALYZE_HEX"); diff --git a/src/afl-common.c b/src/afl-common.c index cf996548..a69f2e97 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -334,6 +334,70 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { } +/* Get libqasan path. */ + +u8 *get_libqasan_path(u8 *own_loc) { + + if (!unlikely(own_loc)) { FATAL("BUG: param own_loc is NULL"); } + + u8 *tmp, *cp = NULL, *rsl, *own_copy; + + tmp = getenv("AFL_PATH"); + + if (tmp) { + + cp = alloc_printf("%s/libqasan.so", tmp); + + if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); } + + return cp; + + } + + own_copy = ck_strdup(own_loc); + rsl = strrchr(own_copy, '/'); + + if (rsl) { + + *rsl = 0; + + cp = alloc_printf("%s/libqasan.so", own_copy); + ck_free(own_copy); + + if (!access(cp, X_OK)) { + + return cp; + + } + + } else { + + ck_free(own_copy); + + } + + if (!access(BIN_PATH "/libqasan.so", X_OK)) { + + if (cp) { ck_free(cp); } + + return ck_strdup(BIN_PATH "/libqasan.so"); + + } + + SAYF("\n" cLRD "[-] " cRST + "Oops, unable to find the 'libqasan.so' binary. The binary must be " + "built\n" + " separately by following the instructions in " + "qemu_mode/libqasan/README.md. " + "If you\n" + " already have the binary installed, you may need to specify " + "AFL_PATH in the\n" + " environment.\n"); + + FATAL("Failed to locate 'libqasan.so'."); + +} + /* Find binary, used by analyze, showmap, tmin @returns the path, allocating the string */ diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 1f5685b0..e59f0d11 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -515,6 +515,10 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "handle_sigill=0", 0); + /* Envs for QASan */ + setenv("QASAN_MAX_CALL_STACK", "0", 0); + setenv("QASAN_SYMBOLIZE", "0", 0); + /* MSAN is tricky, because it doesn't support abort_on_error=1 at this point. So, we do this in a very hacky way. */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e856730e..54850173 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -326,8 +326,32 @@ int main(int argc, char **argv_orig, char **envp) { "compile time)"); } - #endif + + if (getenv("AFL_USE_QASAN")) { + + u8* preload = getenv("AFL_PRELOAD"); + u8* libqasan = get_libqasan_path(argv_orig[0]); + + if (!preload) { + + setenv("AFL_PRELOAD", libqasan, 0); + + } else { + + u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2); + strcpy(result, libqasan); + strcat(result, " "); + strcat(result, preload); + + setenv("AFL_PRELOAD", result, 1); + ck_free(result); + + } + + ck_free(libqasan); + + } char **argv = argv_cpy_dup(argc, argv_orig); @@ -1245,7 +1269,7 @@ int main(int argc, char **argv_orig, char **envp) { "instead of using AFL_PRELOAD?"); } - + if (afl->afl_env.afl_preload) { if (afl->fsrv.qemu_mode) { @@ -1297,7 +1321,7 @@ int main(int argc, char **argv_orig, char **envp) { FATAL("Use AFL_PRELOAD instead of AFL_LD_PRELOAD"); } - + save_cmdline(afl, argc, argv); fix_up_banner(afl, argv[optind]); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 5a0b6ecf..f3cd5a90 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -942,6 +942,31 @@ int main(int argc, char **argv_orig, char **envp) { } if (optind == argc || !out_file) { usage(argv[0]); } + + if (fsrv->qemu_mode && getenv("AFL_USE_QASAN")) { + + u8* preload = getenv("AFL_PRELOAD"); + u8* libqasan = get_libqasan_path(argv_orig[0]); + + if (!preload) { + + setenv("AFL_PRELOAD", libqasan, 0); + + } else { + + u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2); + strcpy(result, libqasan); + strcat(result, " "); + strcat(result, preload); + + setenv("AFL_PRELOAD", result, 1); + ck_free(result); + + } + + ck_free(libqasan); + + } if (in_dir) { diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 5fd60cd2..9e9e2d63 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -1074,6 +1074,31 @@ int main(int argc, char **argv_orig, char **envp) { if (optind == argc || !in_file || !output_file) { usage(argv[0]); } check_environment_vars(envp); + + if (fsrv->qemu_mode && getenv("AFL_USE_QASAN")) { + + u8* preload = getenv("AFL_PRELOAD"); + u8* libqasan = get_libqasan_path(argv_orig[0]); + + if (!preload) { + + setenv("AFL_PRELOAD", libqasan, 0); + + } else { + + u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2); + strcpy(result, libqasan); + strcat(result, " "); + strcat(result, preload); + + setenv("AFL_PRELOAD", result, 1); + ck_free(result); + + } + + ck_free(libqasan); + + } /* initialize cmplog_mode */ shm.cmplog_mode = 0; -- cgit v1.2.3 From 40f609c7354ffa75dea16401d6c22a4eac510910 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 29 Jan 2021 15:57:47 +0100 Subject: better cmplog arithmetic --- src/afl-fuzz-redqueen.c | 194 ++++++++++++++++++++++++++++-------------------- 1 file changed, 114 insertions(+), 80 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 34db7231..5570520a 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -1118,128 +1118,159 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, #ifdef ARITHMETIC_LESSER_GREATER if (lvl < LVL3 || attr == IS_TRANSFORM) { return 0; } + if ((attr & (IS_GREATER | IS_LESSER)) SHAPE_BYTES(h->shape) < 4) { return 0; } + + // transform >= to < and <= to > + if ((attr & IS_EQUAL) && (attr & (IS_GREATER | IS_LESSER))) { + + if (attr & 2) { + + attr += 2; + + } else { + + attr -= 2; + + } + + } + // lesser/greater FP comparison - if ((attr & (IS_LESSER + IS_GREATER)) && - (attr >= IS_FP && attr < IS_FP_MOD)) { + if (attr >= IS_FP && attr < IS_FP_MOD) { - u64 repl_new; - if (SHAPE_BYTES(h->shape) == 4 && its_len >= 4) { + u64 repl_new; - float *f = (float *)&repl; - float g = *f; - g += 1.0; - u32 *r = (u32 *)&g; - repl_new = (u32)*r; + if (attr & IS_GREATER) { - } else if (SHAPE_BYTES(h->shape) == 8 && its_len >= 8) { + if (SHAPE_BYTES(h->shape) == 4 && its_len >= 4) { - double *f = (double *)&repl; - double g = *f; - g += 1.0; + float *f = (float *)&repl; + float g = *f; + g += 1.0; + u32 *r = (u32 *)&g; + repl_new = (u32)*r; - u64 *r = (u64 *)&g; - repl_new = *r; + } else if (SHAPE_BYTES(h->shape) == 8 && its_len >= 8) { - } else { + double *f = (double *)&repl; + double g = *f; + g += 1.0; - return 0; + u64 *r = (u64 *)&g; + repl_new = *r; - } + } else { - changed_val = repl_new; + return 0; - if (unlikely(cmp_extend_encoding(afl, h, pattern, repl_new, o_pattern, - changed_val, 16, idx, taint_len, orig_buf, - buf, cbuf, len, 1, lvl, status))) { + } - return 1; + changed_val = repl_new; - } + if (unlikely(cmp_extend_encoding( + afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx, + taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { - if (SHAPE_BYTES(h->shape) == 4) { + return 1; - float *f = (float *)&repl; - float g = *f; - g -= 1.0; - u32 *r = (u32 *)&g; - repl_new = (u32)*r; + } - } else if (SHAPE_BYTES(h->shape) == 8) { + } else { - double *f = (double *)&repl; - double g = *f; - g -= 1.0; - u64 *r = (u64 *)&g; - repl_new = *r; + if (SHAPE_BYTES(h->shape) == 4) { - } else { + float *f = (float *)&repl; + float g = *f; + g -= 1.0; + u32 *r = (u32 *)&g; + repl_new = (u32)*r; - return 0; + } else if (SHAPE_BYTES(h->shape) == 8) { - } + double *f = (double *)&repl; + double g = *f; + g -= 1.0; + u64 *r = (u64 *)&g; + repl_new = *r; - changed_val = repl_new; + } else { - if (unlikely(cmp_extend_encoding(afl, h, pattern, repl_new, o_pattern, - changed_val, 16, idx, taint_len, orig_buf, - buf, cbuf, len, 1, lvl, status))) { + return 0; - return 1; + } - } + changed_val = repl_new; + + if (unlikely(cmp_extend_encoding( + afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx, + taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { + + return 1; - // transform double to float, llvm likes to do that internally ... - if (SHAPE_BYTES(h->shape) == 8 && its_len >= 4) { + } - double *f = (double *)&repl; - float g = (float)*f; - repl_new = 0; + } + + // transform double to float, llvm likes to do that internally ... + if (SHAPE_BYTES(h->shape) == 8 && its_len >= 4) { + + double *f = (double *)&repl; + float g = (float)*f; + repl_new = 0; #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) - memcpy((char *)&repl_new, (char *)&g, 4); + memcpy((char *)&repl_new, (char *)&g, 4); #else - memcpy(((char *)&repl_new) + 4, (char *)&g, 4); + memcpy(((char *)&repl_new) + 4, (char *)&g, 4); #endif - changed_val = repl_new; - h->shape = 3; // modify shape + changed_val = repl_new; + h->shape = 3; // modify shape - // fprintf(stderr, "DOUBLE2FLOAT %llx\n", repl_new); + // fprintf(stderr, "DOUBLE2FLOAT %llx\n", repl_new); - if (unlikely(cmp_extend_encoding( - afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx, - taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { + if (unlikely(cmp_extend_encoding( + afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx, + taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { + + h->shape = 7; // recover shape + return 1; + + } h->shape = 7; // recover shape - return 1; } - h->shape = 7; // recover shape - } - } else if ((attr & (IS_LESSER + IS_GREATER)) && attr < IS_FP) { + else if (attr < IS_FP) { // lesser/greater integer comparison u64 repl_new; - repl_new = repl + 1; - changed_val = repl_new; - if (unlikely(cmp_extend_encoding(afl, h, pattern, repl_new, o_pattern, - changed_val, 32, idx, taint_len, orig_buf, - buf, cbuf, len, 1, lvl, status))) { + if (attr & IS_GREATER) { + + repl_new = repl + 1; + changed_val = repl_new; + if (unlikely(cmp_extend_encoding( + afl, h, pattern, repl_new, o_pattern, changed_val, 32, idx, + taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { + + return 1; - return 1; + } - } + } else { - repl_new = repl - 1; - changed_val = repl_new; - if (unlikely(cmp_extend_encoding(afl, h, pattern, repl_new, o_pattern, - changed_val, 32, idx, taint_len, orig_buf, - buf, cbuf, len, 1, lvl, status))) { + repl_new = repl - 1; + changed_val = repl_new; + if (unlikely(cmp_extend_encoding( + afl, h, pattern, repl_new, o_pattern, changed_val, 32, idx, + taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { - return 1; + return 1; + + } } @@ -1432,6 +1463,8 @@ static void try_to_add_to_dictN(afl_state_t *afl, u128 v, u8 size) { #endif +#define SWAPA(_x) ((_x & 0xf8) + ((_x & 7) ^ 0x07)) + static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, u32 len, u32 lvl, struct tainted *taint) { @@ -1588,8 +1621,8 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, if (unlikely(cmp_extend_encodingN( afl, h, s128_v1, s128_v0, orig_s128_v1, orig_s128_v0, - h->attribute, idx, taint_len, orig_buf, buf, cbuf, len, 1, - lvl, &status))) { + SWAPA(h->attribute), idx, taint_len, orig_buf, buf, cbuf, len, + 1, lvl, &status))) { return 1; @@ -1634,9 +1667,10 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, status = 0; if ((o->v1 != orig_o->v1 || lvl >= LVL3) && orig_o->v0 != orig_o->v1) { - if (unlikely(cmp_extend_encoding( - afl, h, o->v1, o->v0, orig_o->v1, orig_o->v0, h->attribute, idx, - taint_len, orig_buf, buf, cbuf, len, 1, lvl, &status))) { + if (unlikely(cmp_extend_encoding(afl, h, o->v1, o->v0, orig_o->v1, + orig_o->v0, SWAPA(h->attribute), idx, + taint_len, orig_buf, buf, cbuf, len, 1, + lvl, &status))) { return 1; -- cgit v1.2.3 From 66c290f804636de19017ecc3c9ece4a7af9eed28 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 29 Jan 2021 17:23:19 +0100 Subject: fix compile --- src/afl-fuzz-redqueen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 5570520a..1ef84046 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -31,7 +31,7 @@ //#define _DEBUG #define COMBINE //#define CMPLOG_INTROSPECTION -//#define ARITHMETIC_LESSER_GREATER +#define ARITHMETIC_LESSER_GREATER //#define TRANSFORM //#define TRANSFORM_BASE64 @@ -1118,7 +1118,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, #ifdef ARITHMETIC_LESSER_GREATER if (lvl < LVL3 || attr == IS_TRANSFORM) { return 0; } - if ((attr & (IS_GREATER | IS_LESSER)) SHAPE_BYTES(h->shape) < 4) { return 0; } + if (!(attr & (IS_GREATER | IS_LESSER)) || SHAPE_BYTES(h->shape) < 4) { return 0; } // transform >= to < and <= to > if ((attr & IS_EQUAL) && (attr & (IS_GREATER | IS_LESSER))) { -- cgit v1.2.3 From 8a8ecef6f5a11f3b8b7e43ad7232751aeecc6635 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 29 Jan 2021 18:13:45 +0100 Subject: cmplog lower fail --- src/afl-fuzz-redqueen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 1ef84046..67d505fc 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -2440,8 +2440,8 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { if (!afl->shm.cmp_map->headers[k].hits) { continue; } - if (afl->pass_stats[k].faileds == 0xff || - afl->pass_stats[k].total == 0xff) { + if (afl->pass_stats[k].faileds >= 0x69 || + afl->pass_stats[k].total >= 0x69) { #ifdef _DEBUG fprintf(stderr, "DISABLED %u\n", k); -- cgit v1.2.3 From debd832f36b142e1b0b1bab8a6966848a51878f8 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 29 Jan 2021 18:25:25 +0100 Subject: 32bit fix --- src/afl-fuzz-redqueen.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 1ef84046..fc620781 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -1700,12 +1700,15 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, if (afl->pass_stats[key].total == 0) { +#ifdef WORD_SIZE_64 if (unlikely(is_n)) { try_to_add_to_dictN(afl, s128_v0, SHAPE_BYTES(h->shape)); try_to_add_to_dictN(afl, s128_v1, SHAPE_BYTES(h->shape)); - } else { + } else +#endif + { try_to_add_to_dict(afl, o->v0, SHAPE_BYTES(h->shape)); try_to_add_to_dict(afl, o->v1, SHAPE_BYTES(h->shape)); -- cgit v1.2.3 From 29c1131fe0851d518d06c9ec8c808098dacb12fb Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Fri, 29 Jan 2021 18:32:28 +0100 Subject: working AFL_USE_QASAN --- src/afl-fuzz.c | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 54850173..312d9424 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -328,31 +328,6 @@ int main(int argc, char **argv_orig, char **envp) { } #endif - if (getenv("AFL_USE_QASAN")) { - - u8* preload = getenv("AFL_PRELOAD"); - u8* libqasan = get_libqasan_path(argv_orig[0]); - - if (!preload) { - - setenv("AFL_PRELOAD", libqasan, 0); - - } else { - - u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2); - strcpy(result, libqasan); - strcat(result, " "); - strcat(result, preload); - - setenv("AFL_PRELOAD", result, 1); - ck_free(result); - - } - - ck_free(libqasan); - - } - char **argv = argv_cpy_dup(argc, argv_orig); afl_state_t *afl = calloc(1, sizeof(afl_state_t)); @@ -1009,6 +984,32 @@ int main(int argc, char **argv_orig, char **envp) { usage(argv[0], show_help); } + + if (afl->fsrv.qemu_mode && getenv("AFL_USE_QASAN")) { + + u8* preload = getenv("AFL_PRELOAD"); + u8* libqasan = get_libqasan_path(argv_orig[0]); + + if (!preload) { + + setenv("AFL_PRELOAD", libqasan, 0); + + } else { + + u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2); + strcpy(result, libqasan); + strcat(result, " "); + strcat(result, preload); + + setenv("AFL_PRELOAD", result, 1); + ck_free(result); + + } + + afl->afl_env.afl_preload = (u8 *)getenv("AFL_PRELOAD"); + ck_free(libqasan); + + } if (afl->fsrv.mem_limit && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260; -- cgit v1.2.3 From 3b3565269d0453c9f4b5b2847f809cd5d315fff2 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 30 Jan 2021 14:57:17 +0100 Subject: foreign sync from ctime to mtime (libfuzzer) --- src/afl-fuzz-init.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 84f81112..1808f0a1 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -468,7 +468,7 @@ void read_foreign_testcases(afl_state_t *afl, int first) { afl->foreign_syncs[iter].dir[0] != 0) { if (first) ACTF("Scanning '%s'...", afl->foreign_syncs[iter].dir); - time_t ctime_max = 0; + time_t mtime_max = 0; u8 * name = strrchr(afl->foreign_syncs[iter].dir, '/'); if (!name) { name = afl->foreign_syncs[iter].dir; } if (!strcmp(name, "queue") || !strcmp(name, "out") || @@ -482,8 +482,8 @@ void read_foreign_testcases(afl_state_t *afl, int first) { } - /* We do not use sorting yet and do a more expensive ctime check instead. - a ctimesort() implementation would be better though. */ + /* We do not use sorting yet and do a more expensive mtime check instead. + a mtimesort() implementation would be better though. */ nl_cnt = scandir(afl->foreign_syncs[iter].dir, &nl, NULL, NULL); @@ -537,8 +537,8 @@ void read_foreign_testcases(afl_state_t *afl, int first) { } - /* we detect new files by their ctime */ - if (likely(st.st_ctime <= afl->foreign_syncs[iter].ctime)) { + /* we detect new files by their mtime */ + if (likely(st.st_mtime <= afl->foreign_syncs[iter].mtime)) { ck_free(fn2); continue; @@ -600,11 +600,11 @@ void read_foreign_testcases(afl_state_t *afl, int first) { munmap(mem, st.st_size); close(fd); - if (st.st_ctime > ctime_max) ctime_max = st.st_ctime; + if (st.st_mtime > mtime_max) mtime_max = st.st_mtime; } - afl->foreign_syncs[iter].ctime = ctime_max; + afl->foreign_syncs[iter].mtime = mtime_max; free(nl); /* not tracked */ } -- cgit v1.2.3 From 9d08f0d098c91e69b5fe41674e4c5d05363af604 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sat, 30 Jan 2021 15:39:47 +0100 Subject: added AFL_CMPLOG_ONLY_NEW feature --- src/afl-analyze.c | 22 ++++---- src/afl-common.c | 6 +-- src/afl-fuzz-init.c | 3 ++ src/afl-fuzz-one.c | 5 +- src/afl-fuzz-redqueen.c | 135 +++++++++++++++++++++++++----------------------- src/afl-fuzz-state.c | 7 +++ src/afl-fuzz.c | 35 +++++++------ src/afl-showmap.c | 24 ++++----- src/afl-tmin.c | 24 ++++----- 9 files changed, 137 insertions(+), 124 deletions(-) (limited to 'src') diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 28598ba0..20aef2da 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -1079,28 +1079,28 @@ int main(int argc, char **argv_orig, char **envp) { if (optind == argc || !in_file) { usage(argv[0]); } if (qemu_mode && getenv("AFL_USE_QASAN")) { - - u8* preload = getenv("AFL_PRELOAD"); - u8* libqasan = get_libqasan_path(argv_orig[0]); - + + u8 *preload = getenv("AFL_PRELOAD"); + u8 *libqasan = get_libqasan_path(argv_orig[0]); + if (!preload) { - + setenv("AFL_PRELOAD", libqasan, 0); - + } else { - + u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2); strcpy(result, libqasan); strcat(result, " "); strcat(result, preload); - + setenv("AFL_PRELOAD", result, 1); ck_free(result); - + } - + ck_free(libqasan); - + } map_size = get_map_size(); diff --git a/src/afl-common.c b/src/afl-common.c index a69f2e97..235c4c05 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -364,11 +364,7 @@ u8 *get_libqasan_path(u8 *own_loc) { cp = alloc_printf("%s/libqasan.so", own_copy); ck_free(own_copy); - if (!access(cp, X_OK)) { - - return cp; - - } + if (!access(cp, X_OK)) { return cp; } } else { diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 1808f0a1..2a7864f9 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -25,6 +25,7 @@ #include "afl-fuzz.h" #include +#include "cmplog.h" #ifdef HAVE_AFFINITY @@ -833,6 +834,8 @@ void perform_dry_run(afl_state_t *afl) { } + if (afl->afl_env.afl_cmplog_only_new) { q->colorized = CMPLOG_LVL_MAX; } + u8 *fn = strrchr(q->fname, '/') + 1; ACTF("Attempting dry run with '%s'...", fn); diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index ff766158..0cf889a8 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -26,6 +26,7 @@ #include "afl-fuzz.h" #include #include +#include "cmplog.h" /* MOpt */ @@ -553,7 +554,7 @@ u8 fuzz_one_original(afl_state_t *afl) { if (unlikely(len < 4)) { - afl->queue_cur->colorized = 0xff; + afl->queue_cur->colorized = CMPLOG_LVL_MAX; } else { @@ -2981,7 +2982,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { if (unlikely(len < 4)) { - afl->queue_cur->colorized = 0xff; + afl->queue_cur->colorized = CMPLOG_LVL_MAX; } else { diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index fc620781..d7657c1d 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -1118,7 +1118,11 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, #ifdef ARITHMETIC_LESSER_GREATER if (lvl < LVL3 || attr == IS_TRANSFORM) { return 0; } - if (!(attr & (IS_GREATER | IS_LESSER)) || SHAPE_BYTES(h->shape) < 4) { return 0; } + if (!(attr & (IS_GREATER | IS_LESSER)) || SHAPE_BYTES(h->shape) < 4) { + + return 0; + + } // transform >= to < and <= to > if ((attr & IS_EQUAL) && (attr & (IS_GREATER | IS_LESSER))) { @@ -1138,110 +1142,110 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // lesser/greater FP comparison if (attr >= IS_FP && attr < IS_FP_MOD) { - u64 repl_new; - - if (attr & IS_GREATER) { + u64 repl_new; - if (SHAPE_BYTES(h->shape) == 4 && its_len >= 4) { + if (attr & IS_GREATER) { - float *f = (float *)&repl; - float g = *f; - g += 1.0; - u32 *r = (u32 *)&g; - repl_new = (u32)*r; + if (SHAPE_BYTES(h->shape) == 4 && its_len >= 4) { - } else if (SHAPE_BYTES(h->shape) == 8 && its_len >= 8) { + float *f = (float *)&repl; + float g = *f; + g += 1.0; + u32 *r = (u32 *)&g; + repl_new = (u32)*r; - double *f = (double *)&repl; - double g = *f; - g += 1.0; + } else if (SHAPE_BYTES(h->shape) == 8 && its_len >= 8) { - u64 *r = (u64 *)&g; - repl_new = *r; + double *f = (double *)&repl; + double g = *f; + g += 1.0; - } else { + u64 *r = (u64 *)&g; + repl_new = *r; - return 0; + } else { - } + return 0; - changed_val = repl_new; + } - if (unlikely(cmp_extend_encoding( - afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx, - taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { + changed_val = repl_new; - return 1; + if (unlikely(cmp_extend_encoding( + afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx, + taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { - } + return 1; - } else { + } - if (SHAPE_BYTES(h->shape) == 4) { + } else { - float *f = (float *)&repl; - float g = *f; - g -= 1.0; - u32 *r = (u32 *)&g; - repl_new = (u32)*r; + if (SHAPE_BYTES(h->shape) == 4) { - } else if (SHAPE_BYTES(h->shape) == 8) { + float *f = (float *)&repl; + float g = *f; + g -= 1.0; + u32 *r = (u32 *)&g; + repl_new = (u32)*r; - double *f = (double *)&repl; - double g = *f; - g -= 1.0; - u64 *r = (u64 *)&g; - repl_new = *r; + } else if (SHAPE_BYTES(h->shape) == 8) { - } else { + double *f = (double *)&repl; + double g = *f; + g -= 1.0; + u64 *r = (u64 *)&g; + repl_new = *r; - return 0; + } else { - } + return 0; - changed_val = repl_new; + } - if (unlikely(cmp_extend_encoding( - afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx, - taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { + changed_val = repl_new; - return 1; + if (unlikely(cmp_extend_encoding( + afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx, + taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { - } + return 1; } - // transform double to float, llvm likes to do that internally ... - if (SHAPE_BYTES(h->shape) == 8 && its_len >= 4) { + } - double *f = (double *)&repl; - float g = (float)*f; - repl_new = 0; + // transform double to float, llvm likes to do that internally ... + if (SHAPE_BYTES(h->shape) == 8 && its_len >= 4) { + + double *f = (double *)&repl; + float g = (float)*f; + repl_new = 0; #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) - memcpy((char *)&repl_new, (char *)&g, 4); + memcpy((char *)&repl_new, (char *)&g, 4); #else - memcpy(((char *)&repl_new) + 4, (char *)&g, 4); + memcpy(((char *)&repl_new) + 4, (char *)&g, 4); #endif - changed_val = repl_new; - h->shape = 3; // modify shape - - // fprintf(stderr, "DOUBLE2FLOAT %llx\n", repl_new); + changed_val = repl_new; + h->shape = 3; // modify shape - if (unlikely(cmp_extend_encoding( - afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx, - taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { + // fprintf(stderr, "DOUBLE2FLOAT %llx\n", repl_new); - h->shape = 7; // recover shape - return 1; - - } + if (unlikely(cmp_extend_encoding( + afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx, + taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) { h->shape = 7; // recover shape + return 1; } + h->shape = 7; // recover shape + } + } + else if (attr < IS_FP) { // lesser/greater integer comparison @@ -1707,6 +1711,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, try_to_add_to_dictN(afl, s128_v1, SHAPE_BYTES(h->shape)); } else + #endif { diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 8423a3d1..5040e3ef 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -236,6 +236,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_custom_mutator_only = get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_CMPLOG_ONLY_NEW", + + afl_environment_variable_len)) { + + afl->afl_env.afl_cmplog_only_new = + 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 312d9424..9d9b0434 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -181,6 +181,7 @@ static void usage(u8 *argv0, int more_help) { "AFL_AUTORESUME: resume fuzzing if directory specified by -o already exists\n" "AFL_BENCH_JUST_ONE: run the target just once\n" "AFL_BENCH_UNTIL_CRASH: exit soon when the first crashing input has been found\n" + "AFL_CMPLOG_ONLY_NEW: do not run cmplog on initial testcases (good for resumes!)\n" "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n" "AFL_CUSTOM_MUTATOR_LIBRARY: lib with afl_custom_fuzz() to mutate inputs\n" "AFL_CUSTOM_MUTATOR_ONLY: avoid AFL++'s internal mutators\n" @@ -326,8 +327,9 @@ int main(int argc, char **argv_orig, char **envp) { "compile time)"); } + #endif - + char **argv = argv_cpy_dup(argc, argv_orig); afl_state_t *afl = calloc(1, sizeof(afl_state_t)); @@ -356,8 +358,7 @@ int main(int argc, char **argv_orig, char **envp) { while ((opt = getopt( argc, argv, - "+b:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNo:p:RQs:S:t:T:UV:Wx:Z")) > - 0) { + "+b:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNo:p:RQs:S:t:T:UV:Wx:Z")) > 0) { switch (opt) { @@ -984,31 +985,31 @@ int main(int argc, char **argv_orig, char **envp) { usage(argv[0], show_help); } - + if (afl->fsrv.qemu_mode && getenv("AFL_USE_QASAN")) { - - u8* preload = getenv("AFL_PRELOAD"); - u8* libqasan = get_libqasan_path(argv_orig[0]); - + + u8 *preload = getenv("AFL_PRELOAD"); + u8 *libqasan = get_libqasan_path(argv_orig[0]); + if (!preload) { - + setenv("AFL_PRELOAD", libqasan, 0); - + } else { - + u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2); strcpy(result, libqasan); strcat(result, " "); strcat(result, preload); - + setenv("AFL_PRELOAD", result, 1); ck_free(result); - + } - + afl->afl_env.afl_preload = (u8 *)getenv("AFL_PRELOAD"); ck_free(libqasan); - + } if (afl->fsrv.mem_limit && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260; @@ -1270,7 +1271,7 @@ int main(int argc, char **argv_orig, char **envp) { "instead of using AFL_PRELOAD?"); } - + if (afl->afl_env.afl_preload) { if (afl->fsrv.qemu_mode) { @@ -1322,7 +1323,7 @@ int main(int argc, char **argv_orig, char **envp) { FATAL("Use AFL_PRELOAD instead of AFL_LD_PRELOAD"); } - + save_cmdline(afl, argc, argv); fix_up_banner(afl, argv[optind]); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index f3cd5a90..62bf1021 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -942,30 +942,30 @@ int main(int argc, char **argv_orig, char **envp) { } if (optind == argc || !out_file) { usage(argv[0]); } - + if (fsrv->qemu_mode && getenv("AFL_USE_QASAN")) { - - u8* preload = getenv("AFL_PRELOAD"); - u8* libqasan = get_libqasan_path(argv_orig[0]); - + + u8 *preload = getenv("AFL_PRELOAD"); + u8 *libqasan = get_libqasan_path(argv_orig[0]); + if (!preload) { - + setenv("AFL_PRELOAD", libqasan, 0); - + } else { - + u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2); strcpy(result, libqasan); strcat(result, " "); strcat(result, preload); - + setenv("AFL_PRELOAD", result, 1); ck_free(result); - + } - + ck_free(libqasan); - + } if (in_dir) { diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 9e9e2d63..09b5211d 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -1074,30 +1074,30 @@ int main(int argc, char **argv_orig, char **envp) { if (optind == argc || !in_file || !output_file) { usage(argv[0]); } check_environment_vars(envp); - + if (fsrv->qemu_mode && getenv("AFL_USE_QASAN")) { - - u8* preload = getenv("AFL_PRELOAD"); - u8* libqasan = get_libqasan_path(argv_orig[0]); - + + u8 *preload = getenv("AFL_PRELOAD"); + u8 *libqasan = get_libqasan_path(argv_orig[0]); + if (!preload) { - + setenv("AFL_PRELOAD", libqasan, 0); - + } else { - + u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2); strcpy(result, libqasan); strcat(result, " "); strcat(result, preload); - + setenv("AFL_PRELOAD", result, 1); ck_free(result); - + } - + ck_free(libqasan); - + } /* initialize cmplog_mode */ -- cgit v1.2.3 From 893cd47d9cdbfa44e43d03e7d40a56a0c2ad7936 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 31 Jan 2021 13:03:00 +0100 Subject: disable trimming for -M --- src/afl-fuzz.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 9d9b0434..647a665e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -145,7 +145,7 @@ static void usage(u8 *argv0, int more_help) { "Other stuff:\n" " -M/-S id - distributed mode (see docs/parallel_fuzzing.md)\n" - " -M auto-sets -D and -Z (use -d to disable -D)\n" + " -M auto-sets -D, -Z (use -d to disable -D) and no trimming\n" " -F path - sync to a foreign fuzzer queue directory (requires " "-M, can\n" " be specified up to %u times)\n" @@ -502,6 +502,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->sync_id = ck_strdup(optarg); afl->skip_deterministic = 0; // force deterministic fuzzing afl->old_seed_selection = 1; // force old queue walking seed selection + afl->disable_trim = 1; // disable trimming if ((c = strchr(afl->sync_id, ':'))) { -- cgit v1.2.3 From 7a861498c27997cd7be01a5650d54cff3b87a02e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 31 Jan 2021 15:04:40 +0100 Subject: added support for __afl_coverage_interesting --- src/afl-cc.c | 16 +++++++++------- src/afl-fuzz.c | 5 +++-- 2 files changed, 12 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index b5dcb632..f513764a 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -572,7 +572,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition"; - if (instrument_mode == INSTRUMENT_CFG) + if (instrument_mode == INSTRUMENT_CFG || + instrument_mode == INSTRUMENT_PCGUARD) cc_params[cc_par_cnt++] = alloc_printf( "-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path); else @@ -1670,15 +1671,16 @@ int main(int argc, char **argv, char **envp) { if (compiler_mode == LTO) { if (instrument_mode == 0 || instrument_mode == INSTRUMENT_LTO || - instrument_mode == INSTRUMENT_CFG) { + instrument_mode == INSTRUMENT_CFG || + instrument_mode == INSTRUMENT_PCGUARD) { lto_mode = 1; - if (!instrument_mode) { + // force CFG + // if (!instrument_mode) { - instrument_mode = INSTRUMENT_CFG; - // ptr = instrument_mode_string[instrument_mode]; - - } + instrument_mode = INSTRUMENT_PCGUARD; + // ptr = instrument_mode_string[instrument_mode]; + // } } else if (instrument_mode == INSTRUMENT_LTO || diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 647a665e..82eff61f 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -145,7 +145,8 @@ static void usage(u8 *argv0, int more_help) { "Other stuff:\n" " -M/-S id - distributed mode (see docs/parallel_fuzzing.md)\n" - " -M auto-sets -D, -Z (use -d to disable -D) and no trimming\n" + " -M auto-sets -D, -Z (use -d to disable -D) and no " + "trimming\n" " -F path - sync to a foreign fuzzer queue directory (requires " "-M, can\n" " be specified up to %u times)\n" @@ -502,7 +503,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->sync_id = ck_strdup(optarg); afl->skip_deterministic = 0; // force deterministic fuzzing afl->old_seed_selection = 1; // force old queue walking seed selection - afl->disable_trim = 1; // disable trimming + afl->disable_trim = 1; // disable trimming if ((c = strchr(afl->sync_id, ':'))) { -- cgit v1.2.3 From e5116c6d55185177413104cad1232ca64e04b844 Mon Sep 17 00:00:00 2001 From: aflpp Date: Sun, 31 Jan 2021 17:29:37 +0100 Subject: fix -Z, remove q->next --- src/afl-fuzz-init.c | 102 +++++++++++++++++++++------------------------------ src/afl-fuzz-one.c | 3 +- src/afl-fuzz-queue.c | 39 ++++++++++---------- src/afl-fuzz-stats.c | 10 +++-- src/afl-fuzz.c | 65 ++++++++++---------------------- 5 files changed, 88 insertions(+), 131 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 2a7864f9..56dae48c 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -817,12 +817,15 @@ void read_testcases(afl_state_t *afl, u8 *directory) { void perform_dry_run(afl_state_t *afl) { - struct queue_entry *q = afl->queue; - u32 cal_failures = 0; + struct queue_entry *q; + u32 cal_failures = 0, idx; u8 * skip_crashes = afl->afl_env.afl_skip_crashes; u8 * use_mem; - while (q) { + for (idx = 0; idx < afl->queued_paths; idx++) { + + q = afl->queue_buf[idx]; + if (unlikely(q->disabled)) { continue; } u8 res; s32 fd; @@ -1052,20 +1055,22 @@ void perform_dry_run(afl_state_t *afl) { p->disabled = 1; p->perf_score = 0; - while (p && p->next != q) - p = p->next; - if (p) - p->next = q->next; - else - afl->queue = q->next; + u32 i = 0; + while (unlikely(afl->queue_buf[i]->disabled)) { + + ++i; + + } + + afl->queue = afl->queue_buf[i]; afl->max_depth = 0; - p = afl->queue; - while (p) { + for (i = 0; i < afl->queued_paths; i++) { - if (p->depth > afl->max_depth) afl->max_depth = p->depth; - p = p->next; + if (!afl->queue_buf[i]->disabled && + afl->queue_buf[i]->depth > afl->max_depth) + afl->max_depth = afl->queue_buf[i]->depth; } @@ -1098,8 +1103,6 @@ void perform_dry_run(afl_state_t *afl) { } - q = q->next; - } if (cal_failures) { @@ -1125,31 +1128,23 @@ void perform_dry_run(afl_state_t *afl) { /* Now we remove all entries from the queue that have a duplicate trace map */ - q = afl->queue; - struct queue_entry *p, *prev = NULL; - int duplicates = 0; - -restart_outer_cull_loop: + u32 duplicates = 0, i; - while (q) { + for (idx = 0; idx < afl->queued_paths; idx++) { - if (q->cal_failed || !q->exec_cksum) { goto next_entry; } + q = afl->queue_buf[idx]; + if (q->disabled || q->cal_failed || !q->exec_cksum) { continue; } - restart_inner_cull_loop: + u32 done = 0; + for (i = idx + 1; i < afl->queued_paths && !done; i++) { - p = q->next; + struct queue_entry *p = afl->queue_buf[i]; + if (p->disabled || p->cal_failed || !p->exec_cksum) { continue; } - while (p) { - - if (!p->cal_failed && p->exec_cksum == q->exec_cksum) { + if (p->exec_cksum == q->exec_cksum) { duplicates = 1; - // We do not remove any of the memory allocated because for - // splicing the data might still be interesting. - // We only decouple them from the linked list. - // This will result in some leaks at exit, but who cares. - // we keep the shorter file if (p->len >= q->len) { @@ -1163,8 +1158,6 @@ restart_outer_cull_loop: p->disabled = 1; p->perf_score = 0; - q->next = p->next; - goto restart_inner_cull_loop; } else { @@ -1178,35 +1171,26 @@ restart_outer_cull_loop: q->disabled = 1; q->perf_score = 0; - if (prev) - prev->next = q = p; - else - afl->queue = q = p; - goto restart_outer_cull_loop; + + done = 1; } } - p = p->next; - } - next_entry: - - prev = q; - q = q->next; - } if (duplicates) { afl->max_depth = 0; - q = afl->queue; - while (q) { - if (q->depth > afl->max_depth) afl->max_depth = q->depth; - q = q->next; + for (idx = 0; idx < afl->queued_paths; idx++) { + + if (!afl->queue_buf[idx]->disabled && + afl->queue_buf[idx]->depth > afl->max_depth) + afl->max_depth = afl->queue_buf[idx]->depth; } @@ -1256,11 +1240,15 @@ static void link_or_copy(u8 *old_path, u8 *new_path) { void pivot_inputs(afl_state_t *afl) { struct queue_entry *q = afl->queue; - u32 id = 0; + u32 id = 0, i; ACTF("Creating hard links for all input files..."); - while (q) { + for (i = 0; i < afl->queued_paths; i++) { + + q = afl->queue_buf[i]; + + if (unlikely(q->disabled)) { continue; } u8 *nfn, *rsl = strrchr(q->fname, '/'); u32 orig_id; @@ -1288,19 +1276,14 @@ void pivot_inputs(afl_state_t *afl) { afl->resuming_fuzz = 1; nfn = alloc_printf("%s/queue/%s", afl->out_dir, rsl); - /* Since we're at it, let's also try to find parent and figure out the + /* Since we're at it, let's also get the parent and figure out the appropriate depth for this entry. */ src_str = strchr(rsl + 3, ':'); if (src_str && sscanf(src_str + 1, "%06u", &src_id) == 1) { - struct queue_entry *s = afl->queue; - while (src_id-- && s) { - - s = s->next; - - } + struct queue_entry *s = afl->queue_buf[src_id]; if (s) { q->depth = s->depth + 1; } @@ -1348,7 +1331,6 @@ void pivot_inputs(afl_state_t *afl) { if (q->passed_det) { mark_as_det_done(afl, q); } - q = q->next; ++id; } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 0cf889a8..18291fb7 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -544,7 +544,8 @@ u8 fuzz_one_original(afl_state_t *afl) { if (likely(!afl->old_seed_selection)) orig_perf = perf_score = afl->queue_cur->perf_score; else - orig_perf = perf_score = calculate_score(afl, afl->queue_cur); + afl->queue_cur->perf_score = orig_perf = perf_score = + calculate_score(afl, afl->queue_cur); if (unlikely(perf_score <= 0)) { goto abandon_entry; } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 4442b400..ad3e3b8e 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -143,7 +143,7 @@ void create_alias_table(afl_state_t *afl) { struct queue_entry *q = afl->queue_buf[i]; - if (!q->disabled) { q->perf_score = calculate_score(afl, q); } + if (likely(!q->disabled)) { q->perf_score = calculate_score(afl, q); } sum += q->perf_score; @@ -444,7 +444,6 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { if (afl->queue_top) { - afl->queue_top->next = q; afl->queue_top = q; } else { @@ -465,6 +464,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { AFL_BUF_PARAM(queue), afl->queued_paths * sizeof(struct queue_entry *)); if (unlikely(!queue_buf)) { PFATAL("alloc"); } queue_buf[afl->queued_paths - 1] = q; + q->id = afl->queued_paths - 1; afl->last_path_time = get_cur_time(); @@ -641,10 +641,9 @@ void cull_queue(afl_state_t *afl) { if (likely(!afl->score_changed || afl->non_instrumented_mode)) { return; } - struct queue_entry *q; - u32 len = (afl->fsrv.map_size >> 3); - u32 i; - u8 * temp_v = afl->map_tmp_buf; + u32 len = (afl->fsrv.map_size >> 3); + u32 i; + u8 *temp_v = afl->map_tmp_buf; afl->score_changed = 0; @@ -653,12 +652,9 @@ void cull_queue(afl_state_t *afl) { afl->queued_favored = 0; afl->pending_favored = 0; - q = afl->queue; - - while (q) { + for (i = 0; i < afl->queued_paths; i++) { - q->favored = 0; - q = q->next; + afl->queue_buf[i]->favored = 0; } @@ -697,12 +693,13 @@ void cull_queue(afl_state_t *afl) { } - q = afl->queue; + for (i = 0; i < afl->queued_paths; i++) { + + if (likely(!afl->queue_buf[i]->disabled)) { - while (q) { + mark_as_redundant(afl, afl->queue_buf[i], !afl->queue_buf[i]->favored); - mark_as_redundant(afl, q, !q->favored); - q = q->next; + } } @@ -852,13 +849,15 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { // Don't modify perf_score for unfuzzed seeds if (q->fuzz_level == 0) break; - struct queue_entry *queue_it = afl->queue; - while (queue_it) { + u32 i; + for (i = 0; i < afl->queued_paths; i++) { - fuzz_mu += log2(afl->n_fuzz[q->n_fuzz_entry]); - n_paths++; + if (likely(!afl->queue_buf[i]->disabled)) { - queue_it = queue_it->next; + fuzz_mu += log2(afl->n_fuzz[afl->queue_buf[i]->n_fuzz_entry]); + n_paths++; + + } } diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 82da8176..7e99bf8f 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -1014,8 +1014,8 @@ void show_stats(afl_state_t *afl) { void show_init_stats(afl_state_t *afl) { - struct queue_entry *q = afl->queue; - u32 min_bits = 0, max_bits = 0, max_len = 0, count = 0; + struct queue_entry *q; + u32 min_bits = 0, max_bits = 0, max_len = 0, count = 0, i; u64 min_us = 0, max_us = 0; u64 avg_us = 0; @@ -1028,7 +1028,10 @@ void show_init_stats(afl_state_t *afl) { } - while (q) { + for (i = 0; i < afl->queued_paths; i++) { + + q = afl->queue_buf[i]; + if (unlikely(q->disabled)) { continue; } if (!min_us || q->exec_us < min_us) { min_us = q->exec_us; } if (q->exec_us > max_us) { max_us = q->exec_us; } @@ -1039,7 +1042,6 @@ void show_init_stats(afl_state_t *afl) { if (q->len > max_len) { max_len = q->len; } ++count; - q = q->next; } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 9d9b0434..40d42c11 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1558,45 +1558,6 @@ int main(int argc, char **argv_orig, char **envp) { perform_dry_run(afl); - /* - if (!user_set_cache && afl->q_testcase_max_cache_size) { - - / * The user defined not a fixed number of entries for the cache. - Hence we autodetect a good value. After the dry run inputs are - trimmed and we know the average and max size of the input seeds. - We use this information to set a fitting size to max entries - based on the cache size. * / - - struct queue_entry *q = afl->queue; - u64 size = 0, count = 0, avg = 0, max = 0; - - while (q) { - - ++count; - size += q->len; - if (max < q->len) { max = q->len; } - q = q->next; - - } - - if (count) { - - avg = size / count; - avg = ((avg + max) / 2) + 1; - - } - - if (avg < 10240) { avg = 10240; } - - afl->q_testcase_max_cache_entries = afl->q_testcase_max_cache_size / avg; - - if (afl->q_testcase_max_cache_entries > 32768) - afl->q_testcase_max_cache_entries = 32768; - - } - - */ - if (afl->q_testcase_max_cache_entries) { afl->q_testcase_cache = @@ -1668,7 +1629,10 @@ int main(int argc, char **argv_orig, char **envp) { if (unlikely(afl->old_seed_selection)) { afl->current_entry = 0; - afl->queue_cur = afl->queue; + while (unlikely(afl->queue_buf[afl->current_entry]->disabled)) { + ++afl->current_entry; + } + afl->queue_cur = afl->queue_buf[afl->current_entry]; if (unlikely(seek_to)) { @@ -1800,12 +1764,14 @@ int main(int argc, char **argv_orig, char **envp) { } - struct queue_entry *q = afl->queue; // we must recalculate the scores of all queue entries - while (q) { + for (i = 0; i < (s32)afl->queued_paths; i++) { + + if (likely(!afl->queue_buf[i]->disabled)) { - update_bitmap_score(afl, q); - q = q->next; + update_bitmap_score(afl, afl->queue_buf[i]); + + } } @@ -1847,8 +1813,15 @@ int main(int argc, char **argv_orig, char **envp) { if (unlikely(afl->old_seed_selection)) { - afl->queue_cur = afl->queue_cur->next; - ++afl->current_entry; + while (++afl->current_entry < afl->queued_paths && + afl->queue_buf[afl->current_entry]->disabled) + ; + if (unlikely(afl->current_entry >= afl->queued_paths || + afl->queue_buf[afl->current_entry] == NULL || + afl->queue_buf[afl->current_entry]->disabled)) + afl->queue_cur = NULL; + else + afl->queue_cur = afl->queue_buf[afl->current_entry]; } -- cgit v1.2.3 From cc0210426a5a31d56d8a0e850dcc00d90833afcd Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 31 Jan 2021 17:32:24 +0100 Subject: code-format --- src/afl-fuzz.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 276074a4..f1f92717 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1632,8 +1632,11 @@ int main(int argc, char **argv_orig, char **envp) { afl->current_entry = 0; while (unlikely(afl->queue_buf[afl->current_entry]->disabled)) { + ++afl->current_entry; + } + afl->queue_cur = afl->queue_buf[afl->current_entry]; if (unlikely(seek_to)) { -- cgit v1.2.3 From 981ffb27a8a166b51a06d57fce044ed1eaf1aa62 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 1 Feb 2021 12:01:23 +0100 Subject: making AFL_MAP_SIZE obsolete --- src/afl-forkserver.c | 28 +++++++++++++++----- src/afl-fuzz-init.c | 14 ++++++---- src/afl-fuzz.c | 73 +++++++++++++++++++++++++++++++++++++++++++++------- src/afl-sharedmem.c | 14 ++++++++-- src/afl-showmap.c | 41 +++++++++++++++++++++++++++-- src/afl-tmin.c | 37 +++++++++++++++++++++++--- 6 files changed, 179 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index e59f0d11..9ee59822 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -682,11 +682,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if ((status & FS_OPT_AUTODICT) == FS_OPT_AUTODICT) { - if (ignore_autodict) { - - if (!be_quiet) { WARNF("Ignoring offered AUTODICT feature."); } - - } else { + if (!ignore_autodict) { if (fsrv->add_extra_func == NULL || fsrv->afl_ptr == NULL) { @@ -969,7 +965,9 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } -static void afl_fsrv_kill(afl_forkserver_t *fsrv) { +/* Stop the forkserver and child */ + +void afl_fsrv_kill(afl_forkserver_t *fsrv) { if (fsrv->child_pid > 0) { kill(fsrv->child_pid, fsrv->kill_signal); } if (fsrv->fsrv_pid > 0) { @@ -979,13 +977,28 @@ static void afl_fsrv_kill(afl_forkserver_t *fsrv) { } + close(fsrv->fsrv_ctl_fd); + close(fsrv->fsrv_st_fd); + fsrv->fsrv_pid = -1; + fsrv->child_pid = -1; + +} + +/* Get the map size from the target forkserver */ + +u32 afl_fsrv_get_mapsize(afl_forkserver_t *fsrv, char **argv, + volatile u8 *stop_soon_p, u8 debug_child_output) { + + afl_fsrv_start(fsrv, argv, stop_soon_p, debug_child_output); + return fsrv->map_size; + } /* Delete the current testcase and write the buf to the testcase file */ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { - if (fsrv->shmem_fuzz) { + if (likely(fsrv->use_shmem_fuzz && fsrv->shmem_fuzz)) { if (unlikely(len > MAX_FILE)) len = MAX_FILE; @@ -1042,6 +1055,7 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { } + // fprintf(stderr, "WRITE %d %u\n", fd, len); ck_write(fd, buf, len, fsrv->out_file); if (fsrv->use_stdin) { diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 56dae48c..40ba20c7 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -766,13 +766,16 @@ void read_testcases(afl_state_t *afl, u8 *directory) { } - if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { + /* + if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { - u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); - afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE; - afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1; + u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, + HASH_CONST); afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE; + afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1; - } + } + + */ } @@ -2490,6 +2493,7 @@ void setup_testcase_shmem(afl_state_t *afl) { // we need to set the non-instrumented mode to not overwrite the SHM_ENV_VAR u8 *map = afl_shm_init(afl->shm_fuzz, MAX_FILE + sizeof(u32), 1); + afl->shm_fuzz->shmemfuzz_mode = 1; if (!map) { FATAL("BUG: Zero return from afl_shm_init."); } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index f1f92717..49733594 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -342,7 +342,6 @@ int main(int argc, char **argv_orig, char **envp) { afl->debug = debug; afl_fsrv_init(&afl->fsrv); if (debug) { afl->fsrv.debug = true; } - read_afl_environment(afl, envp); if (afl->shm.map_size) { afl->fsrv.map_size = afl->shm.map_size; } exit_1 = !!afl->afl_env.afl_bench_just_one; @@ -702,7 +701,6 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->in_bitmap) { FATAL("Multiple -B options not supported"); } afl->in_bitmap = optarg; - read_bitmap(afl->in_bitmap, afl->virgin_bits, afl->fsrv.map_size); break; case 'C': /* crash mode */ @@ -1369,13 +1367,6 @@ int main(int argc, char **argv_orig, char **envp) { set_scheduler_mode(SCHEDULER_MODE_LOW_LATENCY); #endif - afl->fsrv.trace_bits = - afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode); - - if (!afl->in_bitmap) { memset(afl->virgin_bits, 255, afl->fsrv.map_size); } - memset(afl->virgin_tmout, 255, afl->fsrv.map_size); - memset(afl->virgin_crash, 255, afl->fsrv.map_size); - init_count_class16(); if (afl->is_main_node && check_main_node_exists(afl) == 1) { @@ -1542,6 +1533,70 @@ int main(int argc, char **argv_orig, char **envp) { } afl->argv = use_argv; + afl->fsrv.trace_bits = + afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode); + + if (!afl->non_instrumented_mode) { + + afl->fsrv.map_size = 4194304; // dummy temporary value + + u32 new_map_size = afl_fsrv_get_mapsize( + &afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); + + if (new_map_size && new_map_size != 4194304) { + + // only reinitialize when it makes sense + if (map_size != new_map_size) { + + // if (map_size < new_map_size || + // (new_map_size > map_size && new_map_size - map_size > + // MAP_SIZE)) { + + OKF("Re-initializing maps to %u bytes", new_map_size); + + afl->virgin_bits = ck_realloc(afl->virgin_bits, map_size); + afl->virgin_tmout = ck_realloc(afl->virgin_tmout, map_size); + afl->virgin_crash = ck_realloc(afl->virgin_crash, map_size); + afl->var_bytes = ck_realloc(afl->var_bytes, map_size); + afl->top_rated = ck_realloc(afl->top_rated, map_size * sizeof(void *)); + afl->clean_trace = ck_realloc(afl->clean_trace, map_size); + afl->clean_trace_custom = ck_realloc(afl->clean_trace_custom, map_size); + afl->first_trace = ck_realloc(afl->first_trace, map_size); + afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, map_size); + + afl_shm_deinit(&afl->shm); + afl_fsrv_kill(&afl->fsrv); + afl->fsrv.map_size = new_map_size; + afl->fsrv.trace_bits = afl_shm_init(&afl->shm, afl->fsrv.map_size, + afl->non_instrumented_mode); + setenv("AFL_NO_AUTODICT", "1", 1); // loaded already + afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, + afl->afl_env.afl_debug_child); + + } + + map_size = new_map_size; + + } + + afl->fsrv.map_size = map_size; + + } + + // after we have the correct bitmap size we can read the bitmap -B option + // and set the virgin maps + if (!afl->in_bitmap) { + + memset(afl->virgin_bits, 255, afl->fsrv.map_size); + + } else { + + read_bitmap(afl->in_bitmap, afl->virgin_bits, afl->fsrv.map_size); + + } + + memset(afl->virgin_tmout, 255, afl->fsrv.map_size); + memset(afl->virgin_crash, 255, afl->fsrv.map_size); if (afl->cmplog_binary) { diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c index fe641d0d..3241a130 100644 --- a/src/afl-sharedmem.c +++ b/src/afl-sharedmem.c @@ -66,9 +66,17 @@ static list_t shm_list = {.element_prealloc_count = 0}; void afl_shm_deinit(sharedmem_t *shm) { - if (shm == NULL) return; - + if (shm == NULL) { return; } list_remove(&shm_list, shm); + if (shm->shmemfuzz_mode) { + + unsetenv(SHM_FUZZ_ENV_VAR); + + } else { + + unsetenv(SHM_ENV_VAR); + + } #ifdef USEMMAP if (shm->map != NULL) { @@ -94,6 +102,8 @@ void afl_shm_deinit(sharedmem_t *shm) { if (shm->cmplog_mode) { + unsetenv(CMPLOG_SHM_ENV_VAR); + if (shm->cmp_map != NULL) { munmap(shm->cmp_map, shm->map_size); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 62bf1021..56abe4f1 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -86,7 +86,8 @@ static u8 quiet_mode, /* Hide non-essential messages? */ remove_shm = 1, /* remove shmem? */ collect_coverage, /* collect coverage */ have_coverage, /* have coverage? */ - no_classify; /* do not classify counts */ + no_classify, /* do not classify counts */ + debug; /* debug mode */ static volatile u8 stop_soon, /* Ctrl-C pressed? */ child_crashed; /* Child crashed? */ @@ -743,6 +744,7 @@ int main(int argc, char **argv_orig, char **envp) { char **argv = argv_cpy_dup(argc, argv_orig); afl_forkserver_t fsrv_var = {0}; + if (getenv("AFL_DEBUG")) { debug = 1; } fsrv = &fsrv_var; afl_fsrv_init(fsrv); map_size = get_map_size(); @@ -991,14 +993,16 @@ int main(int argc, char **argv_orig, char **envp) { // if (afl->shmem_testcase_mode) { setup_testcase_shmem(afl); } + setenv("AFL_NO_AUTODICT", "1", 1); + /* initialize cmplog_mode */ shm.cmplog_mode = 0; - fsrv->trace_bits = afl_shm_init(&shm, map_size, 0); setup_signal_handlers(); set_up_environment(fsrv); fsrv->target_path = find_binary(argv[optind]); + fsrv->trace_bits = afl_shm_init(&shm, map_size, 0); if (!quiet_mode) { @@ -1051,6 +1055,7 @@ int main(int argc, char **argv_orig, char **envp) { /* initialize cmplog_mode */ shm_fuzz->cmplog_mode = 0; u8 *map = afl_shm_init(shm_fuzz, MAX_FILE + sizeof(u32), 1); + shm_fuzz->shmemfuzz_mode = 1; if (!map) { FATAL("BUG: Zero return from afl_shm_init."); } #ifdef USEMMAP setenv(SHM_FUZZ_ENV_VAR, shm_fuzz->g_shm_file_path, 1); @@ -1063,6 +1068,38 @@ int main(int argc, char **argv_orig, char **envp) { fsrv->shmem_fuzz_len = (u32 *)map; fsrv->shmem_fuzz = map + sizeof(u32); + u32 save_be_quiet = be_quiet; + be_quiet = debug; + 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") || get_afl_env("AFL_DEBUG_CHILD_OUTPUT")) + ? 1 + : 0); + be_quiet = save_be_quiet; + + if (new_map_size) { + + // only reinitialize when it makes sense + if (map_size < new_map_size || + (new_map_size > map_size && new_map_size - map_size > MAP_SIZE)) { + + if (!be_quiet) + ACTF("Aquired new map size for target: %u bytes\n", new_map_size); + + afl_shm_deinit(&shm); + afl_fsrv_kill(fsrv); + fsrv->map_size = new_map_size; + fsrv->trace_bits = afl_shm_init(&shm, new_map_size, 0); + + } + + map_size = new_map_size; + + } + + fsrv->map_size = map_size; + if (in_dir) { DIR * dir_in, *dir_out = NULL; diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 09b5211d..799a4b87 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -79,7 +79,8 @@ static u8 crash_mode, /* Crash-centric mode? */ edges_only, /* Ignore hit counts? */ exact_mode, /* Require path match for crashes? */ remove_out_file, /* remove out_file on exit? */ - remove_shm = 1; /* remove shmem on exit? */ + remove_shm = 1, /* remove shmem on exit? */ + debug; /* debug mode */ static volatile u8 stop_soon; /* Ctrl-C pressed? */ @@ -878,6 +879,7 @@ int main(int argc, char **argv_orig, char **envp) { char **argv = argv_cpy_dup(argc, argv_orig); afl_forkserver_t fsrv_var = {0}; + if (getenv("AFL_DEBUG")) { debug = 1; } fsrv = &fsrv_var; afl_fsrv_init(fsrv); map_size = get_map_size(); @@ -1074,6 +1076,7 @@ int main(int argc, char **argv_orig, char **envp) { if (optind == argc || !in_file || !output_file) { usage(argv[0]); } check_environment_vars(envp); + setenv("AFL_NO_AUTODICT", "1", 1); if (fsrv->qemu_mode && getenv("AFL_USE_QASAN")) { @@ -1102,7 +1105,6 @@ int main(int argc, char **argv_orig, char **envp) { /* initialize cmplog_mode */ shm.cmplog_mode = 0; - fsrv->trace_bits = afl_shm_init(&shm, map_size, 0); atexit(at_exit_handler); setup_signal_handlers(); @@ -1110,6 +1112,7 @@ int main(int argc, char **argv_orig, char **envp) { set_up_environment(fsrv); fsrv->target_path = find_binary(argv[optind]); + fsrv->trace_bits = afl_shm_init(&shm, map_size, 0); detect_file_args(argv + optind, out_file, &fsrv->use_stdin); if (fsrv->qemu_mode) { @@ -1181,6 +1184,7 @@ int main(int argc, char **argv_orig, char **envp) { /* initialize cmplog_mode */ shm_fuzz->cmplog_mode = 0; u8 *map = afl_shm_init(shm_fuzz, MAX_FILE + sizeof(u32), 1); + shm_fuzz->shmemfuzz_mode = 1; if (!map) { FATAL("BUG: Zero return from afl_shm_init."); } #ifdef USEMMAP setenv(SHM_FUZZ_ENV_VAR, shm_fuzz->g_shm_file_path, 1); @@ -1195,12 +1199,39 @@ int main(int argc, char **argv_orig, char **envp) { read_initial_file(); - afl_fsrv_start( + 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") || get_afl_env("AFL_DEBUG_CHILD_OUTPUT")) ? 1 : 0); + if (new_map_size) { + + if (map_size < new_map_size || + (new_map_size > map_size && new_map_size - map_size > MAP_SIZE)) { + + if (!be_quiet) + ACTF("Aquired new map size for target: %u bytes\n", new_map_size); + + afl_shm_deinit(&shm); + afl_fsrv_kill(fsrv); + fsrv->map_size = new_map_size; + fsrv->trace_bits = afl_shm_init(&shm, new_map_size, 0); + afl_fsrv_start(fsrv, use_argv, &stop_soon, + (get_afl_env("AFL_DEBUG_CHILD") || + get_afl_env("AFL_DEBUG_CHILD_OUTPUT")) + ? 1 + : 0); + + } + + map_size = new_map_size; + + } + + fsrv->map_size = map_size; + if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz); -- cgit v1.2.3 From 965b854803b67f952406d31353d4cb8ed26eeee6 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 1 Feb 2021 12:05:54 +0100 Subject: correct afl-showmap be_quiet state --- src/afl-showmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 56abe4f1..56091357 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1069,7 +1069,7 @@ int main(int argc, char **argv_orig, char **envp) { fsrv->shmem_fuzz = map + sizeof(u32); u32 save_be_quiet = be_quiet; - be_quiet = debug; + be_quiet = !debug; fsrv->map_size = 4194304; // dummy temporary value u32 new_map_size = afl_fsrv_get_mapsize( fsrv, use_argv, &stop_soon, -- cgit v1.2.3 From d808a8401e1acbcde3352d86e9e2da3f7bac97e8 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 1 Feb 2021 12:16:55 +0100 Subject: import cmplog opts --- src/afl-fuzz-one.c | 4 ++-- src/afl-fuzz-redqueen.c | 31 +++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 18291fb7..c73e394a 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -562,7 +562,7 @@ u8 fuzz_one_original(afl_state_t *afl) { if (afl->cmplog_lvl == 3 || (afl->cmplog_lvl == 2 && afl->queue_cur->tc_ref) || !(afl->fsrv.total_execs % afl->queued_paths) || - get_cur_time() - afl->last_path_time > 15000) { + get_cur_time() - afl->last_path_time > 300000) { if (input_to_state_stage(afl, in_buf, out_buf, len)) { @@ -2990,7 +2990,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { if (afl->cmplog_lvl == 3 || (afl->cmplog_lvl == 2 && afl->queue_cur->tc_ref) || !(afl->fsrv.total_execs % afl->queued_paths) || - get_cur_time() - afl->last_path_time > 15000) { + get_cur_time() - afl->last_path_time > 300000) { if (input_to_state_stage(afl, in_buf, out_buf, len)) { diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 74c9db38..997b7528 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -379,8 +379,6 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, } - *taints = taint; - /* temporary: clean ranges */ while (ranges) { @@ -423,6 +421,35 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, #endif + if (taint) { + + if (len / positions == 1 && positions > 16384 && + afl->active_paths / afl->colorize_success > 20) { + +#ifdef _DEBUG + fprintf(stderr, "Colorization unsatisfactory\n"); +#endif + + *taints = NULL; + + struct tainted *t; + while (taint) { + + t = taint->next; + ck_free(taint); + taint = t; + + } + + } else { + + *taints = taint; + ++afl->colorize_success; + + } + + } + afl->stage_finds[STAGE_COLORIZATION] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_COLORIZATION] += afl->stage_cur; ck_free(backup); -- cgit v1.2.3 From 88155d2c3b86aa2b042e57481939cf2a7d3b02f4 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 1 Feb 2021 13:04:39 +0100 Subject: make dominik more happy - no auto map size for qemu+unicorn --- src/afl-fuzz.c | 3 ++- src/afl-showmap.c | 57 +++++++++++++++++++++++++--------------------- src/afl-tmin.c | 67 +++++++++++++++++++++++++++++++++---------------------- 3 files changed, 73 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 49733594..edcc14d6 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1536,7 +1536,8 @@ int main(int argc, char **argv_orig, char **envp) { afl->fsrv.trace_bits = afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode); - if (!afl->non_instrumented_mode) { + if (!afl->non_instrumented_mode && !afl->fsrv.qemu_mode && + !afl->unicorn_mode) { afl->fsrv.map_size = 4194304; // dummy temporary value diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 56091357..c424cdf3 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1068,38 +1068,43 @@ int main(int argc, char **argv_orig, char **envp) { fsrv->shmem_fuzz_len = (u32 *)map; fsrv->shmem_fuzz = map + sizeof(u32); - u32 save_be_quiet = be_quiet; - be_quiet = !debug; - 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") || get_afl_env("AFL_DEBUG_CHILD_OUTPUT")) - ? 1 - : 0); - be_quiet = save_be_quiet; - - if (new_map_size) { - - // only reinitialize when it makes sense - if (map_size < new_map_size || - (new_map_size > map_size && new_map_size - map_size > MAP_SIZE)) { - - if (!be_quiet) - ACTF("Aquired new map size for target: %u bytes\n", new_map_size); - - afl_shm_deinit(&shm); - afl_fsrv_kill(fsrv); - fsrv->map_size = new_map_size; - fsrv->trace_bits = afl_shm_init(&shm, new_map_size, 0); + if (!fsrv->qemu_mode && !unicorn_mode) { + + u32 save_be_quiet = be_quiet; + be_quiet = !debug; + 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") || + get_afl_env("AFL_DEBUG_CHILD_OUTPUT")) + ? 1 + : 0); + be_quiet = save_be_quiet; + + if (new_map_size) { + + // only reinitialize when it makes sense + if (map_size < new_map_size || + (new_map_size > map_size && new_map_size - map_size > MAP_SIZE)) { + + if (!be_quiet) + ACTF("Aquired new map size for target: %u bytes\n", new_map_size); + + afl_shm_deinit(&shm); + afl_fsrv_kill(fsrv); + fsrv->map_size = new_map_size; + fsrv->trace_bits = afl_shm_init(&shm, new_map_size, 0); + + } + + map_size = new_map_size; } - map_size = new_map_size; + fsrv->map_size = map_size; } - fsrv->map_size = map_size; - if (in_dir) { DIR * dir_in, *dir_out = NULL; diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 799a4b87..15336959 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -1199,38 +1199,51 @@ int main(int argc, char **argv_orig, char **envp) { read_initial_file(); - 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") || get_afl_env("AFL_DEBUG_CHILD_OUTPUT")) - ? 1 - : 0); - - if (new_map_size) { - - if (map_size < new_map_size || - (new_map_size > map_size && new_map_size - map_size > MAP_SIZE)) { - - if (!be_quiet) - ACTF("Aquired new map size for target: %u bytes\n", new_map_size); - - afl_shm_deinit(&shm); - afl_fsrv_kill(fsrv); - fsrv->map_size = new_map_size; - fsrv->trace_bits = afl_shm_init(&shm, new_map_size, 0); - afl_fsrv_start(fsrv, use_argv, &stop_soon, - (get_afl_env("AFL_DEBUG_CHILD") || - get_afl_env("AFL_DEBUG_CHILD_OUTPUT")) - ? 1 - : 0); + if (!fsrv->qemu_mode && !unicorn_mode) { + + 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") || + get_afl_env("AFL_DEBUG_CHILD_OUTPUT")) + ? 1 + : 0); + + if (new_map_size) { + + if (map_size < new_map_size || + (new_map_size > map_size && new_map_size - map_size > MAP_SIZE)) { + + if (!be_quiet) + ACTF("Aquired new map size for target: %u bytes\n", new_map_size); + + afl_shm_deinit(&shm); + afl_fsrv_kill(fsrv); + fsrv->map_size = new_map_size; + fsrv->trace_bits = afl_shm_init(&shm, new_map_size, 0); + afl_fsrv_start(fsrv, use_argv, &stop_soon, + (get_afl_env("AFL_DEBUG_CHILD") || + get_afl_env("AFL_DEBUG_CHILD_OUTPUT")) + ? 1 + : 0); + + } + + map_size = new_map_size; } - map_size = new_map_size; + fsrv->map_size = map_size; - } + } else { - fsrv->map_size = map_size; + afl_fsrv_start(fsrv, use_argv, &stop_soon, + (get_afl_env("AFL_DEBUG_CHILD") || + get_afl_env("AFL_DEBUG_CHILD_OUTPUT")) + ? 1 + : 0); + + } if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz); -- cgit v1.2.3 From 374fa8af4788960ef4a0f5462370b68be6e4fc90 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 1 Feb 2021 14:56:22 +0100 Subject: add case when cmplog map neds to be larger --- src/afl-fuzz.c | 85 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index edcc14d6..b3a27fc6 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1547,11 +1547,8 @@ int main(int argc, char **argv_orig, char **envp) { if (new_map_size && new_map_size != 4194304) { // only reinitialize when it makes sense - if (map_size != new_map_size) { - - // if (map_size < new_map_size || - // (new_map_size > map_size && new_map_size - map_size > - // MAP_SIZE)) { + if (map_size < new_map_size || + (new_map_size > map_size && new_map_size - map_size > MAP_SIZE)) { OKF("Re-initializing maps to %u bytes", new_map_size); @@ -1584,21 +1581,6 @@ int main(int argc, char **argv_orig, char **envp) { } - // after we have the correct bitmap size we can read the bitmap -B option - // and set the virgin maps - if (!afl->in_bitmap) { - - memset(afl->virgin_bits, 255, afl->fsrv.map_size); - - } else { - - read_bitmap(afl->in_bitmap, afl->virgin_bits, afl->fsrv.map_size); - - } - - memset(afl->virgin_tmout, 255, afl->fsrv.map_size); - memset(afl->virgin_crash, 255, afl->fsrv.map_size); - if (afl->cmplog_binary) { ACTF("Spawning cmplog forkserver"); @@ -1608,12 +1590,71 @@ int main(int argc, char **argv_orig, char **envp) { afl->cmplog_fsrv.qemu_mode = afl->fsrv.qemu_mode; afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary; afl->cmplog_fsrv.init_child_func = cmplog_exec_child; - afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, - afl->afl_env.afl_debug_child); + + afl->cmplog_fsrv.map_size = 4194304; + + u32 new_map_size = + afl_fsrv_get_mapsize(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, + afl->afl_env.afl_debug_child); + + if (new_map_size && new_map_size != 4194304) { + + // only reinitialize when it needs to be larger + if (map_size < new_map_size) { + + OKF("Re-initializing maps to %u bytes", new_map_size); + + afl->virgin_bits = ck_realloc(afl->virgin_bits, map_size); + afl->virgin_tmout = ck_realloc(afl->virgin_tmout, map_size); + afl->virgin_crash = ck_realloc(afl->virgin_crash, map_size); + afl->var_bytes = ck_realloc(afl->var_bytes, map_size); + afl->top_rated = ck_realloc(afl->top_rated, map_size * sizeof(void *)); + afl->clean_trace = ck_realloc(afl->clean_trace, map_size); + afl->clean_trace_custom = ck_realloc(afl->clean_trace_custom, map_size); + afl->first_trace = ck_realloc(afl->first_trace, map_size); + afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, map_size); + + afl_shm_deinit(&afl->shm); + afl_fsrv_kill(&afl->fsrv); + afl_fsrv_kill(&afl->cmplog_fsrv); + afl->cmplog_fsrv.map_size = new_map_size; // non-cmplog stays the same + + afl->fsrv.trace_bits = afl_shm_init(&afl->shm, new_map_size, + afl->non_instrumented_mode); + setenv("AFL_NO_AUTODICT", "1", 1); // loaded already + afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, + afl->afl_env.afl_debug_child); + + afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, + afl->afl_env.afl_debug_child); + + map_size = new_map_size; + + } + + } + + afl->cmplog_fsrv.map_size = map_size; + OKF("Cmplog forkserver successfully started"); } + // after we have the correct bitmap size we can read the bitmap -B option + // and set the virgin maps + if (afl->in_bitmap) { + + read_bitmap(afl->in_bitmap, afl->virgin_bits, afl->fsrv.map_size); + + } else { + + memset(afl->virgin_bits, 255, map_size); + + } + + memset(afl->virgin_tmout, 255, map_size); + memset(afl->virgin_crash, 255, map_size); + perform_dry_run(afl); if (afl->q_testcase_max_cache_entries) { -- cgit v1.2.3 From 812cf4c9e0f8eff80b8f46907fc8dfcd9458919f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 1 Feb 2021 15:21:39 +0100 Subject: reorder --- src/afl-fuzz.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index b3a27fc6..d8ebe097 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1562,10 +1562,10 @@ int main(int argc, char **argv_orig, char **envp) { afl->first_trace = ck_realloc(afl->first_trace, map_size); afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, map_size); - afl_shm_deinit(&afl->shm); afl_fsrv_kill(&afl->fsrv); + afl_shm_deinit(&afl->shm); afl->fsrv.map_size = new_map_size; - afl->fsrv.trace_bits = afl_shm_init(&afl->shm, afl->fsrv.map_size, + afl->fsrv.trace_bits = afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); setenv("AFL_NO_AUTODICT", "1", 1); // loaded already afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, @@ -1602,7 +1602,7 @@ int main(int argc, char **argv_orig, char **envp) { // only reinitialize when it needs to be larger if (map_size < new_map_size) { - OKF("Re-initializing maps to %u bytes", new_map_size); + OKF("Re-initializing maps to %u bytes due cmplog", new_map_size); afl->virgin_bits = ck_realloc(afl->virgin_bits, map_size); afl->virgin_tmout = ck_realloc(afl->virgin_tmout, map_size); @@ -1614,9 +1614,9 @@ int main(int argc, char **argv_orig, char **envp) { afl->first_trace = ck_realloc(afl->first_trace, map_size); afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, map_size); - afl_shm_deinit(&afl->shm); afl_fsrv_kill(&afl->fsrv); afl_fsrv_kill(&afl->cmplog_fsrv); + afl_shm_deinit(&afl->shm); afl->cmplog_fsrv.map_size = new_map_size; // non-cmplog stays the same afl->fsrv.trace_bits = afl_shm_init(&afl->shm, new_map_size, -- cgit v1.2.3 From 32110a04c0101a77a43088b85f1465ba321b2bc4 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 1 Feb 2021 15:51:04 +0100 Subject: fixes --- src/afl-common.c | 2 +- src/afl-fuzz.c | 38 ++++++++++++++++++++------------------ 2 files changed, 21 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 235c4c05..1cc7f462 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -981,7 +981,7 @@ u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) { /* Reads the map size from ENV */ u32 get_map_size(void) { - uint32_t map_size = MAP_SIZE; + uint32_t map_size = (MAP_SIZE << 2); // needed for target ctors :( char * ptr; if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index d8ebe097..008ba7d1 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1540,6 +1540,7 @@ int main(int argc, char **argv_orig, char **envp) { !afl->unicorn_mode) { afl->fsrv.map_size = 4194304; // dummy temporary value + setenv("AFL_MAP_SIZE", "4194304", 1); u32 new_map_size = afl_fsrv_get_mapsize( &afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); @@ -1552,15 +1553,15 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Re-initializing maps to %u bytes", new_map_size); - afl->virgin_bits = ck_realloc(afl->virgin_bits, map_size); - afl->virgin_tmout = ck_realloc(afl->virgin_tmout, map_size); - afl->virgin_crash = ck_realloc(afl->virgin_crash, map_size); - afl->var_bytes = ck_realloc(afl->var_bytes, map_size); - afl->top_rated = ck_realloc(afl->top_rated, map_size * sizeof(void *)); - afl->clean_trace = ck_realloc(afl->clean_trace, map_size); - afl->clean_trace_custom = ck_realloc(afl->clean_trace_custom, map_size); - afl->first_trace = ck_realloc(afl->first_trace, map_size); - afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, map_size); + afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size); + afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); + afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); + afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size); + afl->top_rated = ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); + afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size); + afl->clean_trace_custom = ck_realloc(afl->clean_trace_custom, new_map_size); + afl->first_trace = ck_realloc(afl->first_trace, new_map_size); + afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); afl_fsrv_kill(&afl->fsrv); afl_shm_deinit(&afl->shm); @@ -1596,6 +1597,7 @@ int main(int argc, char **argv_orig, char **envp) { u32 new_map_size = afl_fsrv_get_mapsize(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); +printf("NEW MAP SIZE2 %u (is %u)\n", new_map_size, map_size); if (new_map_size && new_map_size != 4194304) { @@ -1604,15 +1606,15 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Re-initializing maps to %u bytes due cmplog", new_map_size); - afl->virgin_bits = ck_realloc(afl->virgin_bits, map_size); - afl->virgin_tmout = ck_realloc(afl->virgin_tmout, map_size); - afl->virgin_crash = ck_realloc(afl->virgin_crash, map_size); - afl->var_bytes = ck_realloc(afl->var_bytes, map_size); - afl->top_rated = ck_realloc(afl->top_rated, map_size * sizeof(void *)); - afl->clean_trace = ck_realloc(afl->clean_trace, map_size); - afl->clean_trace_custom = ck_realloc(afl->clean_trace_custom, map_size); - afl->first_trace = ck_realloc(afl->first_trace, map_size); - afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, map_size); + afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size); + afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); + afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); + afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size); + afl->top_rated = ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); + afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size); + afl->clean_trace_custom = ck_realloc(afl->clean_trace_custom, new_map_size); + afl->first_trace = ck_realloc(afl->first_trace, new_map_size); + afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); afl_fsrv_kill(&afl->fsrv); afl_fsrv_kill(&afl->cmplog_fsrv); -- cgit v1.2.3 From 05472a0fc5767c90811bd55b927d26b1784c403d Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 1 Feb 2021 16:04:34 +0100 Subject: move cmplog compile options to config.h --- src/afl-fuzz-redqueen.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 997b7528..14a9b65d 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -29,11 +29,9 @@ #include "cmplog.h" //#define _DEBUG -#define COMBINE //#define CMPLOG_INTROSPECTION +#define COMBINE #define ARITHMETIC_LESSER_GREATER -//#define TRANSFORM -//#define TRANSFORM_BASE64 // CMP attribute enum enum { @@ -423,8 +421,8 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, if (taint) { - if (len / positions == 1 && positions > 16384 && - afl->active_paths / afl->colorize_success > 20) { + if (len / positions == 1 && positions > CMPLOG_POSITIONS_MAX && + afl->active_paths / afl->colorize_success > CMPLOG_CORPUS_PERCENT) { #ifdef _DEBUG fprintf(stderr, "Colorization unsatisfactory\n"); @@ -498,7 +496,7 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) { } -#ifdef TRANSFORM +#ifdef CMPLOG_TRANSFORM static int strntoll(const char *str, size_t sz, char **end, int base, long long *out) { @@ -579,7 +577,7 @@ static int is_hex(const char *str) { } - #ifdef TRANSFORM_BASE64 + #ifdef CMPLOG_TRANSFORM_BASE64 // tests 4 bytes at location static int is_base64(const char *str) { @@ -719,7 +717,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // o_pattern, pattern, repl, changed_val, idx, taint_len, // h->shape + 1, attr); -#ifdef TRANSFORM +#ifdef CMPLOG_TRANSFORM // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3 if (lvl & LVL3) { @@ -1783,7 +1781,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, #ifndef COMBINE (void)(cbuf); #endif -#ifndef TRANSFORM +#ifndef CMPLOG_TRANSFORM (void)(changed_val); #endif @@ -1865,14 +1863,14 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } -#ifdef TRANSFORM +#ifdef CMPLOG_TRANSFORM if (*status == 1) return 0; if (lvl & LVL3) { u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, fromhex = 0; - #ifdef TRANSFORM_BASE64 + #ifdef CMPLOG_TRANSFORM_BASE64 u32 tob64 = 0, fromb64 = 0; #endif u32 from_0 = 0, from_x = 0, from_X = 0, from_slash = 0, from_up = 0; @@ -1970,7 +1968,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - #ifdef TRANSFORM_BASE64 + #ifdef CMPLOG_TRANSFORM_BASE64 if (i % 3 == 2 && i < 24) { if (is_base64(repl + ((i / 3) << 2))) tob64 += 3; @@ -2018,13 +2016,13 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, "from_0=%u from_slash=%u from_x=%u\n", idx, i, xor, arith, tolower, toupper, tohex, fromhex, to_0, to_slash, to_x, from_0, from_slash, from_x); - #ifdef TRANSFORM_BASE64 + #ifdef CMPLOG_TRANSFORM_BASE64 fprintf(stderr, "RTN idx=%u loop=%u tob64=%u from64=%u\n", tob64, fromb64); #endif #endif - #ifdef TRANSFORM_BASE64 + #ifdef CMPLOG_TRANSFORM_BASE64 // input is base64 and converted to binary? convert repl to base64! if ((i % 4) == 3 && i < 24 && fromb64 > i) { @@ -2183,7 +2181,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, if ((i >= 7 && (i >= xor&&i >= arith &&i >= tolower &&i >= toupper &&i > tohex &&i > (fromhex + from_0 + from_x + from_slash + 1) - #ifdef TRANSFORM_BASE64 + #ifdef CMPLOG_TRANSFORM_BASE64 && i > tob64 + 3 && i > fromb64 + 4 #endif )) || @@ -2518,7 +2516,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } else if ((lvl & LVL1) -#ifdef TRANSFORM +#ifdef CMPLOG_TRANSFORM || (lvl & LVL3) #endif ) { -- cgit v1.2.3 From 4018e7f8e5e45ccef83d740d7bc2514dc4f602f0 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 1 Feb 2021 16:23:40 +0100 Subject: mv cmplog options to config.h --- src/afl-fuzz-redqueen.c | 35 ++++++++++------------------------- src/afl-fuzz.c | 3 +-- 2 files changed, 11 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 14a9b65d..8979be98 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -51,7 +51,7 @@ enum { enum { LVL1 = 1, // Integer solving - LVL2 = 2, // FP solving + LVL2 = 2, // unused except for setting the queue entry LVL3 = 4 // expensive tranformations }; @@ -986,11 +986,10 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, #endif - // we only allow this for ascii2integer (above) + // we only allow this for ascii2integer (above) so leave if this is the case if (unlikely(pattern == o_pattern)) { return 0; } - if ((lvl & LVL1) || ((lvl & LVL2) && (attr >= IS_FP && attr < IS_FP_MOD)) || - attr >= IS_FP_MOD) { + if ((lvl & LVL1) || attr >= IS_FP_MOD) { if (SHAPE_BYTES(h->shape) >= 8 && *status != 1) { @@ -1498,9 +1497,6 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, u32 len, u32 lvl, struct tainted *taint) { struct cmp_header *h = &afl->shm.cmp_map->headers[key]; - // FP handling only from lvl 2 onwards - if ((h->attribute & IS_FP) && lvl < LVL2) { return 0; } - struct tainted *t; u32 i, j, idx, taint_len, loggeds; u32 have_taint = 1, is_n = 0; @@ -2443,21 +2439,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { afl->stage_max = 0; afl->stage_cur = 0; - u32 lvl; - u32 cmplog_done = afl->queue_cur->colorized; - u32 cmplog_lvl = afl->cmplog_lvl; - if (!cmplog_done) { - - lvl = LVL1; - - } else { - - lvl = 0; - - } - - if (cmplog_lvl >= 2 && cmplog_done < 2) { lvl += LVL2; } - if (cmplog_lvl >= 3 && cmplog_done < 3) { lvl += LVL3; } + u32 lvl = (afl->queue_cur->colorized ? 0 : LVL1) + (afl->cmplog_lvl == CMPLOG_LVL_MAX ? LVL3 : 0); #ifdef COMBINE u8 *cbuf = afl_realloc((void **)&afl->in_scratch_buf, len + 128); @@ -2473,8 +2455,8 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { if (!afl->shm.cmp_map->headers[k].hits) { continue; } - if (afl->pass_stats[k].faileds >= 0x69 || - afl->pass_stats[k].total >= 0x69) { + if (afl->pass_stats[k].faileds >= CMPLOG_FAIL_MAX || + afl->pass_stats[k].total >= CMPLOG_FAIL_MAX) { #ifdef _DEBUG fprintf(stderr, "DISABLED %u\n", k); @@ -2542,9 +2524,10 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { exit_its: - afl->queue_cur->colorized = afl->cmplog_lvl; if (afl->cmplog_lvl == CMPLOG_LVL_MAX) { + afl->queue_cur->colorized = CMPLOG_LVL_MAX; + ck_free(afl->queue_cur->cmplog_colorinput); t = taint; while (taint) { @@ -2559,6 +2542,8 @@ exit_its: } else { + afl->queue_cur->colorized = LVL2; + if (!afl->queue_cur->taint) { afl->queue_cur->taint = taint; } if (!afl->queue_cur->cmplog_colorinput) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 008ba7d1..62560724 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -123,8 +123,7 @@ static void usage(u8 *argv0, int more_help) { "it.\n" " if using QEMU, just use -c 0.\n" " -l cmplog_level - set the complexity/intensivity of CmpLog.\n" - " Values: 1 (integer+string), 2 (+FP) and 3 " - "(+transform)\n\n" + " Values: 1 (basic), 2 (larger files) and 3 (transform)\n\n" "Fuzzing behavior settings:\n" " -Z - sequential queue selection instead of weighted " -- cgit v1.2.3 From 80fc6166d0aeaf6332a00c369f7bdb872066e1b9 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 1 Feb 2021 16:28:52 +0100 Subject: adjust expand havoc --- src/afl-fuzz.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 62560724..4a23d99d 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1779,6 +1779,7 @@ printf("NEW MAP SIZE2 %u (is %u)\n", new_map_size, map_size); break; case 1: // add MOpt mutator + /* if (afl->limit_time_sig == 0 && !afl->custom_only && !afl->python_only) { @@ -1786,12 +1787,11 @@ printf("NEW MAP SIZE2 %u (is %u)\n", new_map_size, map_size); afl->limit_time_puppet = 0; } - + */ afl->expand_havoc = 2; - if (afl->cmplog_lvl < 2) afl->cmplog_lvl = 2; + if (afl->cmplog_lvl && afl->cmplog_lvl < 2) afl->cmplog_lvl = 2; break; case 2: - // if (!have_p) afl->schedule = EXPLOIT; // increase havoc mutations per fuzz attempt afl->havoc_stack_pow2++; afl->expand_havoc = 3; @@ -1803,11 +1803,11 @@ printf("NEW MAP SIZE2 %u (is %u)\n", new_map_size, map_size); break; case 4: afl->expand_havoc = 5; - if (afl->cmplog_lvl < 3) afl->cmplog_lvl = 3; + if (afl->cmplog_lvl && afl->cmplog_lvl < 3) afl->cmplog_lvl = 3; break; case 5: // if not in sync mode, enable deterministic mode? - if (!afl->sync_id) afl->skip_deterministic = 0; + //if (!afl->sync_id) afl->skip_deterministic = 0; afl->expand_havoc = 6; case 6: // nothing else currently -- cgit v1.2.3 From b9f469e12fde797e301845caa4b0fd44315318bd Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 1 Feb 2021 20:00:29 +0100 Subject: make some really weird targets compile --- src/afl-cc.c | 1 + src/afl-fuzz.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index f513764a..7db3c9a0 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -689,6 +689,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue; if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue; if (!strncmp(cur, "-fno-unroll", 11)) continue; + if (strstr(cur, "afl-compiler-rt") || strstr(cur, "afl-llvm-rt")) continue; if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined")) continue; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 4a23d99d..3a7343ae 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1596,7 +1596,6 @@ int main(int argc, char **argv_orig, char **envp) { u32 new_map_size = afl_fsrv_get_mapsize(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); -printf("NEW MAP SIZE2 %u (is %u)\n", new_map_size, map_size); if (new_map_size && new_map_size != 4194304) { -- cgit v1.2.3 From 90fdafa1ad167f43fb42cdec2335fa7416cc633c Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 1 Feb 2021 22:59:41 +0100 Subject: fix warnings and an llvm cmplog+lto panic --- src/afl-fuzz-redqueen.c | 13 +++++++------ src/afl-fuzz.c | 26 ++++++++++++++++---------- src/afl-ld-lto.c | 14 ++++++++------ 3 files changed, 31 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 8979be98..f619a6d3 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -1497,10 +1497,10 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, u32 len, u32 lvl, struct tainted *taint) { struct cmp_header *h = &afl->shm.cmp_map->headers[key]; - struct tainted *t; - u32 i, j, idx, taint_len, loggeds; - u32 have_taint = 1, is_n = 0; - u8 status = 0, found_one = 0; + struct tainted * t; + u32 i, j, idx, taint_len, loggeds; + u32 have_taint = 1, is_n = 0; + u8 status = 0, found_one = 0; /* loop cmps are useless, detect and ignore them */ #ifdef WORD_SIZE_64 @@ -2439,7 +2439,8 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { afl->stage_max = 0; afl->stage_cur = 0; - u32 lvl = (afl->queue_cur->colorized ? 0 : LVL1) + (afl->cmplog_lvl == CMPLOG_LVL_MAX ? LVL3 : 0); + u32 lvl = (afl->queue_cur->colorized ? 0 : LVL1) + + (afl->cmplog_lvl == CMPLOG_LVL_MAX ? LVL3 : 0); #ifdef COMBINE u8 *cbuf = afl_realloc((void **)&afl->in_scratch_buf, len + 128); @@ -2527,7 +2528,7 @@ exit_its: if (afl->cmplog_lvl == CMPLOG_LVL_MAX) { afl->queue_cur->colorized = CMPLOG_LVL_MAX; - + ck_free(afl->queue_cur->cmplog_colorinput); t = taint; while (taint) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 3a7343ae..a579a8f5 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -123,7 +123,8 @@ static void usage(u8 *argv0, int more_help) { "it.\n" " if using QEMU, just use -c 0.\n" " -l cmplog_level - set the complexity/intensivity of CmpLog.\n" - " Values: 1 (basic), 2 (larger files) and 3 (transform)\n\n" + " Values: 1 (basic), 2 (larger files) and 3 " + "(transform)\n\n" "Fuzzing behavior settings:\n" " -Z - sequential queue selection instead of weighted " @@ -1556,17 +1557,19 @@ int main(int argc, char **argv_orig, char **envp) { afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size); - afl->top_rated = ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); + afl->top_rated = + ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size); - afl->clean_trace_custom = ck_realloc(afl->clean_trace_custom, new_map_size); + afl->clean_trace_custom = + ck_realloc(afl->clean_trace_custom, new_map_size); afl->first_trace = ck_realloc(afl->first_trace, new_map_size); afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); afl_fsrv_kill(&afl->fsrv); afl_shm_deinit(&afl->shm); afl->fsrv.map_size = new_map_size; - afl->fsrv.trace_bits = afl_shm_init(&afl->shm, new_map_size, - afl->non_instrumented_mode); + afl->fsrv.trace_bits = + afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); setenv("AFL_NO_AUTODICT", "1", 1); // loaded already afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); @@ -1608,9 +1611,11 @@ int main(int argc, char **argv_orig, char **envp) { afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size); - afl->top_rated = ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); + afl->top_rated = + ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size); - afl->clean_trace_custom = ck_realloc(afl->clean_trace_custom, new_map_size); + afl->clean_trace_custom = + ck_realloc(afl->clean_trace_custom, new_map_size); afl->first_trace = ck_realloc(afl->first_trace, new_map_size); afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); @@ -1619,8 +1624,8 @@ int main(int argc, char **argv_orig, char **envp) { afl_shm_deinit(&afl->shm); afl->cmplog_fsrv.map_size = new_map_size; // non-cmplog stays the same - afl->fsrv.trace_bits = afl_shm_init(&afl->shm, new_map_size, - afl->non_instrumented_mode); + afl->fsrv.trace_bits = + afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); setenv("AFL_NO_AUTODICT", "1", 1); // loaded already afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); @@ -1786,6 +1791,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->limit_time_puppet = 0; } + */ afl->expand_havoc = 2; if (afl->cmplog_lvl && afl->cmplog_lvl < 2) afl->cmplog_lvl = 2; @@ -1806,7 +1812,7 @@ int main(int argc, char **argv_orig, char **envp) { break; case 5: // if not in sync mode, enable deterministic mode? - //if (!afl->sync_id) afl->skip_deterministic = 0; + // if (!afl->sync_id) afl->skip_deterministic = 0; afl->expand_havoc = 6; case 6: // nothing else currently diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index 1fb01600..0a978653 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -83,7 +83,7 @@ static void edit_params(int argc, char **argv) { if (!passthrough) { - for (i = 1; i < argc; i++) { + for (i = 1; i < (u32)argc; i++) { if (strstr(argv[i], "/afl-llvm-rt-lto.o") != NULL) rt_lto_present = 1; if (strstr(argv[i], "/afl-llvm-rt.o") != NULL) rt_present = 1; @@ -91,7 +91,7 @@ static void edit_params(int argc, char **argv) { } - for (i = 1; i < argc && !gold_pos; i++) { + for (i = 1; i < (u32)argc && !gold_pos; i++) { if (strcmp(argv[i], "-plugin") == 0) { @@ -100,7 +100,9 @@ static void edit_params(int argc, char **argv) { if (strcasestr(argv[i], "LLVMgold.so") != NULL) gold_present = gold_pos = i + 1; - } else if (i < argc && strcasestr(argv[i + 1], "LLVMgold.so") != NULL) { + } else if (i < (u32)argc && + + strcasestr(argv[i + 1], "LLVMgold.so") != NULL) { gold_present = gold_pos = i + 2; @@ -112,7 +114,7 @@ static void edit_params(int argc, char **argv) { if (!gold_pos) { - for (i = 1; i + 1 < argc && !gold_pos; i++) { + for (i = 1; i + 1 < (u32)argc && !gold_pos; i++) { if (argv[i][0] != '-') { @@ -198,7 +200,7 @@ static void edit_params(int argc, char **argv) { gold_present ? "true" : "false", inst_present ? "true" : "false", rt_present ? "true" : "false", rt_lto_present ? "true" : "false"); - for (i = 1; i < argc; i++) { + for (i = 1; i < (u32)argc; i++) { if (ld_param_cnt >= MAX_PARAM_COUNT) FATAL( @@ -324,7 +326,7 @@ int main(int argc, char **argv) { if (debug) { DEBUGF("cd \"%s\";", thecwd); - for (i = 0; i < ld_param_cnt; i++) + for (i = 0; i < (s32)ld_param_cnt; i++) SAYF(" \"%s\"", ld_params[i]); SAYF("\n"); -- cgit v1.2.3 From 654f389e73c9fd5b7e141b33ea28ab0fdda3178f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 1 Feb 2021 23:36:27 +0100 Subject: try to remove warnings during compilation --- src/afl-cc.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 7db3c9a0..f272f0b5 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -313,7 +313,8 @@ static u8 *find_object(u8 *obj, u8 *argv0) { static void edit_params(u32 argc, char **argv, char **envp) { u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0, shared_linking = 0, - preprocessor_only = 0, have_unroll = 0, have_o = 0, have_pic = 0; + preprocessor_only = 0, have_unroll = 0, have_o = 0, have_pic = 0, + have_c = 0; u8 *name; cc_params = ck_alloc((argc + 128) * sizeof(u8 *)); @@ -461,7 +462,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { // laf if (getenv("LAF_SPLIT_SWITCHES") || getenv("AFL_LLVM_LAF_SPLIT_SWITCHES")) { - if (lto_mode) { + if (lto_mode && !have_c) { cc_params[cc_par_cnt++] = alloc_printf( "-Wl,-mllvm=-load=%s/split-switches-pass.so", obj_path); @@ -481,7 +482,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (getenv("LAF_TRANSFORM_COMPARES") || getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")) { - if (lto_mode) { + if (lto_mode && !have_c) { cc_params[cc_par_cnt++] = alloc_printf( "-Wl,-mllvm=-load=%s/compare-transform-pass.so", obj_path); @@ -501,7 +502,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (getenv("LAF_SPLIT_COMPARES") || getenv("AFL_LLVM_LAF_SPLIT_COMPARES") || getenv("AFL_LLVM_LAF_SPLIT_FLOATS")) { - if (lto_mode) { + if (lto_mode && !have_c) { cc_params[cc_par_cnt++] = alloc_printf( "-Wl,-mllvm=-load=%s/split-compares-pass.so", obj_path); @@ -524,7 +525,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { unsetenv("AFL_LD_CALLER"); if (cmplog_mode) { - if (lto_mode) { + if (lto_mode && !have_c) { cc_params[cc_par_cnt++] = alloc_printf( "-Wl,-mllvm=-load=%s/cmplog-routines-pass.so", obj_path); @@ -560,7 +561,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } - if (lto_mode) { + if (lto_mode && !have_c) { u8 *ld_path = strdup(AFL_REAL_LD); if (!*ld_path) ld_path = "ld.lld"; @@ -708,6 +709,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (!strcmp(cur, "-x")) x_set = 1; if (!strcmp(cur, "-E")) preprocessor_only = 1; if (!strcmp(cur, "-shared")) shared_linking = 1; + if (!strcmp(cur, "-c")) have_c = 1; if (!strncmp(cur, "-O", 2)) have_o = 1; if (!strncmp(cur, "-funroll-loop", 13)) have_unroll = 1; @@ -800,7 +802,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { } #if defined(USEMMAP) && !defined(__HAIKU__) - cc_params[cc_par_cnt++] = "-lrt"; + if (!have_c) + cc_params[cc_par_cnt++] = "-lrt"; #endif cc_params[cc_par_cnt++] = "-D__AFL_HAVE_MANUAL_CONTROL=1"; @@ -967,15 +970,19 @@ static void edit_params(u32 argc, char **argv, char **envp) { } #if !defined(__APPLE__) && !defined(__sun) - if (!shared_linking) + if (!shared_linking && !have_c) cc_params[cc_par_cnt++] = alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); #endif #if defined(USEMMAP) && !defined(__HAIKU__) - cc_params[cc_par_cnt++] = "-lrt"; + if (!have_c) + cc_params[cc_par_cnt++] = "-lrt"; #endif + // prevent unnecessary build errors + cc_params[cc_par_cnt++] = "-Wno-unused-command-line-argument"; + } #endif -- cgit v1.2.3 From 1f71b85426f837ebcae8381897d44a3a67c73a4f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 2 Feb 2021 10:05:10 +0100 Subject: automagically fix sanitize fuzzer+coverage --- src/afl-cc.c | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index f272f0b5..cba435bd 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -693,6 +693,38 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (strstr(cur, "afl-compiler-rt") || strstr(cur, "afl-llvm-rt")) continue; if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined")) continue; + if (!strncmp(cur, "-fsanitize=fuzzer-", strlen("-fsanitize=fuzzer-")) || + !strncmp(cur, "-fsanitize-coverage", strlen("-fsanitize-coverage"))) { + + if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); } + continue; + + } + + if (!strcmp(cur, "-fsanitize=fuzzer")) { + + u8 *afllib = find_object("libAFLDriver.a", argv[0]); + + if (!be_quiet) + WARNF( + "Found errornous '-fsanitize=fuzzer', trying to replace with " + "libAFLDriver.a"); + + if (!afllib) { + + WARNF( + "Cannot find 'libAFLDriver.a' to replace a wrong " + "'-fsanitize=fuzzer' in the flags - this will fail!"); + + } else { + + cc_params[cc_par_cnt++] = afllib; + + } + + continue; + + } if (!strcmp(cur, "-m32")) bit_mode = 32; if (!strcmp(cur, "armv7a-linux-androideabi")) bit_mode = 32; @@ -802,8 +834,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } #if defined(USEMMAP) && !defined(__HAIKU__) - if (!have_c) - cc_params[cc_par_cnt++] = "-lrt"; + if (!have_c) cc_params[cc_par_cnt++] = "-lrt"; #endif cc_params[cc_par_cnt++] = "-D__AFL_HAVE_MANUAL_CONTROL=1"; @@ -976,12 +1007,11 @@ static void edit_params(u32 argc, char **argv, char **envp) { #endif #if defined(USEMMAP) && !defined(__HAIKU__) - if (!have_c) - cc_params[cc_par_cnt++] = "-lrt"; + if (!have_c) cc_params[cc_par_cnt++] = "-lrt"; #endif - // prevent unnecessary build errors - cc_params[cc_par_cnt++] = "-Wno-unused-command-line-argument"; + // prevent unnecessary build errors + cc_params[cc_par_cnt++] = "-Wno-unused-command-line-argument"; } -- cgit v1.2.3 From 58a5372bf0c55ead2a04ed4a4a5b651d68e69292 Mon Sep 17 00:00:00 2001 From: hexcoder Date: Wed, 3 Feb 2021 14:18:35 +0100 Subject: typo --- src/afl-cc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index cba435bd..cf10d9a7 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -707,7 +707,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (!be_quiet) WARNF( - "Found errornous '-fsanitize=fuzzer', trying to replace with " + "Found erroneous '-fsanitize=fuzzer', trying to replace with " "libAFLDriver.a"); if (!afllib) { -- cgit v1.2.3 From 6f163bb0c50a103dc4565ec5f0b8b9b94b5c16f6 Mon Sep 17 00:00:00 2001 From: vj-27 Date: Fri, 5 Feb 2021 00:26:23 +0000 Subject: load existing stats file when in AFL_AUTORESUME or -i - --- src/afl-fuzz-stats.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/afl-fuzz.c | 1 + 2 files changed, 102 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 7e99bf8f..d75b8405 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -89,6 +89,107 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { } +/* load some of the existing stats file when resuming.*/ +void load_stats_file(afl_state_t *afl) { + + FILE *f; + u8 buf[MAX_LINE]; + u8 * lptr; + u8 fn[PATH_MAX]; + u32 lineno = 0; + + snprintf(fn, PATH_MAX, "%s/fuzzer_stats", afl->out_dir); + f = fopen(fn, "r"); + if (!f) { + + WARNF("Unable to load stats file '%s'", fn); + return; + + } + + while ((lptr = fgets(buf, MAX_LINE, f))) { + + lineno++; + u8 *lstartptr = lptr; + u8 *rptr = lptr + strlen(lptr) - 1; + u8 keystring[MAX_LINE]; + while (*lptr != ':' && lptr < rptr) { + + lptr++; + + } + + if (*lptr == '\n' || !*lptr) { + + WARNF("Unable to read line %d of stats file", lineno); + continue; + + } + + if (*lptr == ':') { + + *lptr = 0; + strcpy(keystring, lstartptr); + lptr++; + char *nptr; + switch (lineno) { + + case 5: + if (!strcmp(keystring, "cycles_done ")) + afl->queue_cycle = + strtoull(lptr, &nptr, 10) ? strtoull(lptr, &nptr, 10) + 1 : 0; + break; + case 7: + if (!strcmp(keystring, "execs_done ")) + afl->fsrv.total_execs = strtoull(lptr, &nptr, 10); + break; + case 10: + if (!strcmp(keystring, "paths_total ")) + afl->queued_paths = strtoul(lptr, &nptr, 10); + break; + case 11: + if (!strcmp(keystring, "paths_favored ")) + afl->queued_favored = strtoul(lptr, &nptr, 10); + break; + case 12: + if (!strcmp(keystring, "paths_found ")) + afl->queued_discovered = strtoul(lptr, &nptr, 10); + break; + case 13: + if (!strcmp(keystring, "paths_imported ")) + afl->queued_imported = strtoul(lptr, &nptr, 10); + break; + case 14: + if (!strcmp(keystring, "max_depth ")) + afl->max_depth = strtoul(lptr, &nptr, 10); + break; + case 16: + if (!strcmp(keystring, "pending_favs ")) + afl->pending_favored = strtoul(lptr, &nptr, 10); + break; + case 17: + if (!strcmp(keystring, "pending_total ")) + afl->pending_not_fuzzed = strtoul(lptr, &nptr, 10); + break; + case 21: + if (!strcmp(keystring, "unique_crashes ")) + afl->unique_crashes = strtoull(lptr, &nptr, 10); + break; + case 22: + if (!strcmp(keystring, "unique_hangs ")) + afl->unique_hangs = strtoull(lptr, &nptr, 10); + break; + default: + break; + + } + + } + + } + +} + /* Update stats file for unattended monitoring. */ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index a579a8f5..6c617b18 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1682,6 +1682,7 @@ int main(int argc, char **argv_orig, char **envp) { if (unlikely(afl->old_seed_selection)) seek_to = find_start_position(afl); + if (afl->in_place_resume || afl->afl_env.afl_autoresume) load_stats_file(afl); write_stats_file(afl, 0, 0, 0); maybe_update_plot_file(afl, 0, 0); save_auto(afl); -- cgit v1.2.3 From 1a8c242d280066b7bfb36897c91215d4f4b5eb01 Mon Sep 17 00:00:00 2001 From: vj-27 Date: Fri, 5 Feb 2021 19:46:24 +0000 Subject: load run time and donot load pending_* or *_favoured --- src/afl-fuzz-stats.c | 29 ++++++++++++++--------------- src/afl-fuzz.c | 8 +++++++- 2 files changed, 21 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index d75b8405..3edb5bb6 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -90,20 +90,20 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { } /* load some of the existing stats file when resuming.*/ -void load_stats_file(afl_state_t *afl) { +u32 load_stats_file(afl_state_t *afl) { FILE *f; u8 buf[MAX_LINE]; u8 * lptr; u8 fn[PATH_MAX]; u32 lineno = 0; - + u32 prev_run_time = 0; snprintf(fn, PATH_MAX, "%s/fuzzer_stats", afl->out_dir); f = fopen(fn, "r"); if (!f) { WARNF("Unable to load stats file '%s'", fn); - return; + return prev_run_time; } @@ -134,6 +134,15 @@ void load_stats_file(afl_state_t *afl) { char *nptr; switch (lineno) { + case 3: + if (!strcmp(keystring, "run_time ")) { + + prev_run_time = 1000 * strtoull(lptr, &nptr, 10); + afl->start_time -= prev_run_time; + + } + + break; case 5: if (!strcmp(keystring, "cycles_done ")) afl->queue_cycle = @@ -147,10 +156,6 @@ void load_stats_file(afl_state_t *afl) { if (!strcmp(keystring, "paths_total ")) afl->queued_paths = strtoul(lptr, &nptr, 10); break; - case 11: - if (!strcmp(keystring, "paths_favored ")) - afl->queued_favored = strtoul(lptr, &nptr, 10); - break; case 12: if (!strcmp(keystring, "paths_found ")) afl->queued_discovered = strtoul(lptr, &nptr, 10); @@ -163,14 +168,6 @@ void load_stats_file(afl_state_t *afl) { if (!strcmp(keystring, "max_depth ")) afl->max_depth = strtoul(lptr, &nptr, 10); break; - case 16: - if (!strcmp(keystring, "pending_favs ")) - afl->pending_favored = strtoul(lptr, &nptr, 10); - break; - case 17: - if (!strcmp(keystring, "pending_total ")) - afl->pending_not_fuzzed = strtoul(lptr, &nptr, 10); - break; case 21: if (!strcmp(keystring, "unique_crashes ")) afl->unique_crashes = strtoull(lptr, &nptr, 10); @@ -188,6 +185,8 @@ void load_stats_file(afl_state_t *afl) { } + return prev_run_time; + } /* Update stats file for unattended monitoring. */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 6c617b18..b7cd251a 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1682,7 +1682,11 @@ int main(int argc, char **argv_orig, char **envp) { if (unlikely(afl->old_seed_selection)) seek_to = find_start_position(afl); - if (afl->in_place_resume || afl->afl_env.afl_autoresume) load_stats_file(afl); + u32 prev_run_time = 0; // to not call load_stats_file again after line 1705 + afl->start_time = get_cur_time(); // without this, time taken for + // perform_dry_run gets added to run time. + if (afl->in_place_resume || afl->afl_env.afl_autoresume) + prev_run_time = load_stats_file(afl); write_stats_file(afl, 0, 0, 0); maybe_update_plot_file(afl, 0, 0); save_auto(afl); @@ -1701,6 +1705,8 @@ int main(int argc, char **argv_orig, char **envp) { // (void)nice(-20); // does not improve the speed // real start time, we reset, so this works correctly with -V afl->start_time = get_cur_time(); + if (afl->in_place_resume || afl->afl_env.afl_autoresume) + afl->start_time -= prev_run_time; u32 runs_in_current_cycle = (u32)-1; u32 prev_queued_paths = 0; -- cgit v1.2.3 From f54c4dbfdb17a06798b337a2182d7cf33ec178dd Mon Sep 17 00:00:00 2001 From: vj-27 Date: Sat, 6 Feb 2021 09:41:15 +0000 Subject: set prev_run_time inside afl state --- src/afl-fuzz-stats.c | 12 ++++++------ src/afl-fuzz.c | 6 ++---- 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 3edb5bb6..880551d3 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -90,20 +90,20 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { } /* load some of the existing stats file when resuming.*/ -u32 load_stats_file(afl_state_t *afl) { +void load_stats_file(afl_state_t *afl) { FILE *f; u8 buf[MAX_LINE]; u8 * lptr; u8 fn[PATH_MAX]; u32 lineno = 0; - u32 prev_run_time = 0; + afl->prev_run_time = 0; snprintf(fn, PATH_MAX, "%s/fuzzer_stats", afl->out_dir); f = fopen(fn, "r"); if (!f) { WARNF("Unable to load stats file '%s'", fn); - return prev_run_time; + return; } @@ -137,8 +137,8 @@ u32 load_stats_file(afl_state_t *afl) { case 3: if (!strcmp(keystring, "run_time ")) { - prev_run_time = 1000 * strtoull(lptr, &nptr, 10); - afl->start_time -= prev_run_time; + afl->prev_run_time = 1000 * strtoull(lptr, &nptr, 10); + afl->start_time -= afl->prev_run_time; } @@ -185,7 +185,7 @@ u32 load_stats_file(afl_state_t *afl) { } - return prev_run_time; + return; } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index b7cd251a..08724959 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1682,11 +1682,9 @@ int main(int argc, char **argv_orig, char **envp) { if (unlikely(afl->old_seed_selection)) seek_to = find_start_position(afl); - u32 prev_run_time = 0; // to not call load_stats_file again after line 1705 afl->start_time = get_cur_time(); // without this, time taken for // perform_dry_run gets added to run time. - if (afl->in_place_resume || afl->afl_env.afl_autoresume) - prev_run_time = load_stats_file(afl); + if (afl->in_place_resume || afl->afl_env.afl_autoresume) load_stats_file(afl); write_stats_file(afl, 0, 0, 0); maybe_update_plot_file(afl, 0, 0); save_auto(afl); @@ -1706,7 +1704,7 @@ int main(int argc, char **argv_orig, char **envp) { // real start time, we reset, so this works correctly with -V afl->start_time = get_cur_time(); if (afl->in_place_resume || afl->afl_env.afl_autoresume) - afl->start_time -= prev_run_time; + afl->start_time -= afl->prev_run_time; u32 runs_in_current_cycle = (u32)-1; u32 prev_queued_paths = 0; -- cgit v1.2.3 From d920104248a6c5387267561382636de404938675 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 6 Feb 2021 12:26:35 +0100 Subject: remove compiler warnings --- src/afl-cc.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index cf10d9a7..76f4a437 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1840,6 +1840,8 @@ int main(int argc, char **argv, char **envp) { for (i = 0; i < argc; i++) SAYF(" '%s'", argv[i]); SAYF("\n"); + fflush(stdout); + fflush(stderr); } @@ -1880,6 +1882,8 @@ int main(int argc, char **argv, char **envp) { for (i = 0; i < (s32)cc_par_cnt; i++) SAYF(" '%s'", cc_params[i]); SAYF("\n"); + fflush(stdout); + fflush(stderr); } -- cgit v1.2.3 From 96cdc97c98ee2e2af7df59252f4f0df1689afb7b Mon Sep 17 00:00:00 2001 From: vj-27 Date: Sun, 7 Feb 2021 03:33:47 +0530 Subject: prev_run_time loaded used only for ui and when writing the stats file --- src/afl-fuzz-stats.c | 25 ++++++++++--------------- src/afl-fuzz.c | 5 +---- 2 files changed, 11 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 880551d3..66efeb20 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -97,7 +97,6 @@ void load_stats_file(afl_state_t *afl) { u8 * lptr; u8 fn[PATH_MAX]; u32 lineno = 0; - afl->prev_run_time = 0; snprintf(fn, PATH_MAX, "%s/fuzzer_stats", afl->out_dir); f = fopen(fn, "r"); if (!f) { @@ -135,13 +134,8 @@ void load_stats_file(afl_state_t *afl) { switch (lineno) { case 3: - if (!strcmp(keystring, "run_time ")) { - + if (!strcmp(keystring, "run_time ")) afl->prev_run_time = 1000 * strtoull(lptr, &nptr, 10); - afl->start_time -= afl->prev_run_time; - - } - break; case 5: if (!strcmp(keystring, "cycles_done ")) @@ -279,12 +273,13 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, "\n" "target_mode : %s%s%s%s%s%s%s%s%s\n" "command_line : %s\n", - afl->start_time / 1000, cur_time / 1000, - (cur_time - afl->start_time) / 1000, (u32)getpid(), - afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->cycles_wo_finds, - afl->fsrv.total_execs, + (afl->start_time - afl->prev_run_time) / 1000, cur_time / 1000, + (afl->prev_run_time + cur_time - afl->start_time) / 1000, + (u32)getpid(), afl->queue_cycle ? (afl->queue_cycle - 1) : 0, + afl->cycles_wo_finds, afl->fsrv.total_execs, afl->fsrv.total_execs / - ((double)(get_cur_time() - afl->start_time) / 1000), + ((double)(afl->prev_run_time + get_cur_time() - afl->start_time) / + 1000), afl->last_avg_execs_saved, afl->queued_paths, afl->queued_favored, afl->queued_discovered, afl->queued_imported, afl->max_depth, afl->current_entry, afl->pending_favored, afl->pending_not_fuzzed, @@ -479,8 +474,8 @@ void show_stats(afl_state_t *afl) { if (likely(cur_ms != afl->start_time)) { - afl->stats_avg_exec = - ((double)afl->fsrv.total_execs) * 1000 / (cur_ms - afl->start_time); + afl->stats_avg_exec = ((double)afl->fsrv.total_execs) * 1000 / + (afl->prev_run_time + cur_ms - afl->start_time); } @@ -692,7 +687,7 @@ void show_stats(afl_state_t *afl) { } - u_stringify_time_diff(time_tmp, cur_ms, afl->start_time); + u_stringify_time_diff(time_tmp, afl->prev_run_time + cur_ms, afl->start_time); SAYF(bV bSTOP " run time : " cRST "%-33s " bSTG bV bSTOP " cycles done : %s%-5s " bSTG bV "\n", time_tmp, tmp, u_stringify_int(IB(0), afl->queue_cycle - 1)); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 08724959..e4139857 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1682,8 +1682,7 @@ int main(int argc, char **argv_orig, char **envp) { if (unlikely(afl->old_seed_selection)) seek_to = find_start_position(afl); - afl->start_time = get_cur_time(); // without this, time taken for - // perform_dry_run gets added to run time. + afl->start_time = get_cur_time(); if (afl->in_place_resume || afl->afl_env.afl_autoresume) load_stats_file(afl); write_stats_file(afl, 0, 0, 0); maybe_update_plot_file(afl, 0, 0); @@ -1703,8 +1702,6 @@ int main(int argc, char **argv_orig, char **envp) { // (void)nice(-20); // does not improve the speed // real start time, we reset, so this works correctly with -V afl->start_time = get_cur_time(); - if (afl->in_place_resume || afl->afl_env.afl_autoresume) - afl->start_time -= afl->prev_run_time; u32 runs_in_current_cycle = (u32)-1; u32 prev_queued_paths = 0; -- cgit v1.2.3 From 209c5ba4657b641bf261da7ac9ce7d3f809109c2 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 7 Feb 2021 05:33:02 +0100 Subject: larger map, stats reload fix, code format --- src/afl-fuzz-bitmap.c | 3 ++- src/afl-fuzz-statsd.c | 63 ++++++++++++++++++++++++++++----------------------- 2 files changed, 37 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 0c4a114e..4ed59364 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -325,7 +325,8 @@ u8 *describe_op(afl_state_t *afl, u8 new_bits, size_t max_description_len) { } - sprintf(ret + strlen(ret), ",time:%llu", get_cur_time() - afl->start_time); + sprintf(ret + strlen(ret), ",time:%llu", + get_cur_time() + afl->prev_run_time - afl->start_time); if (afl->current_custom_fuzz && afl->current_custom_fuzz->afl_custom_describe) { diff --git a/src/afl-fuzz-statsd.c b/src/afl-fuzz-statsd.c index 69cafd90..461bbbf6 100644 --- a/src/afl-fuzz-statsd.c +++ b/src/afl-fuzz-statsd.c @@ -1,3 +1,8 @@ +/* + * This implements rpc.statsd support, see docs/rpc_statsd.md + * + */ + #include #include #include @@ -226,37 +231,39 @@ int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen) { */ if (afl->statsd_metric_format_type == STATSD_TAGS_TYPE_SUFFIX) { - snprintf(buff, bufflen, afl->statsd_metric_format, - afl->queue_cycle ? (afl->queue_cycle - 1) : 0, tags, - afl->cycles_wo_finds, tags, afl->fsrv.total_execs, tags, - afl->fsrv.total_execs / - ((double)(get_cur_time() - afl->start_time) / 1000), - tags, afl->queued_paths, tags, afl->queued_favored, tags, - afl->queued_discovered, tags, afl->queued_imported, tags, - afl->max_depth, tags, afl->current_entry, tags, - afl->pending_favored, tags, afl->pending_not_fuzzed, tags, - afl->queued_variable, tags, afl->unique_crashes, tags, - afl->unique_hangs, tags, afl->total_crashes, tags, - afl->slowest_exec_ms, tags, - count_non_255_bytes(afl, afl->virgin_bits), tags, - afl->var_byte_count, tags, afl->expand_havoc, tags); + snprintf( + buff, bufflen, afl->statsd_metric_format, + afl->queue_cycle ? (afl->queue_cycle - 1) : 0, tags, + afl->cycles_wo_finds, tags, afl->fsrv.total_execs, tags, + afl->fsrv.total_execs / + ((double)(get_cur_time() + afl->prev_run_time - afl->start_time) / + 1000), + tags, afl->queued_paths, tags, afl->queued_favored, tags, + afl->queued_discovered, tags, afl->queued_imported, tags, + afl->max_depth, tags, afl->current_entry, tags, afl->pending_favored, + tags, afl->pending_not_fuzzed, tags, afl->queued_variable, tags, + afl->unique_crashes, tags, afl->unique_hangs, tags, afl->total_crashes, + tags, afl->slowest_exec_ms, tags, + count_non_255_bytes(afl, afl->virgin_bits), tags, afl->var_byte_count, + tags, afl->expand_havoc, tags); } else if (afl->statsd_metric_format_type == STATSD_TAGS_TYPE_MID) { - snprintf(buff, bufflen, afl->statsd_metric_format, tags, - afl->queue_cycle ? (afl->queue_cycle - 1) : 0, tags, - afl->cycles_wo_finds, tags, afl->fsrv.total_execs, tags, - afl->fsrv.total_execs / - ((double)(get_cur_time() - afl->start_time) / 1000), - tags, afl->queued_paths, tags, afl->queued_favored, tags, - afl->queued_discovered, tags, afl->queued_imported, tags, - afl->max_depth, tags, afl->current_entry, tags, - afl->pending_favored, tags, afl->pending_not_fuzzed, tags, - afl->queued_variable, tags, afl->unique_crashes, tags, - afl->unique_hangs, tags, afl->total_crashes, tags, - afl->slowest_exec_ms, tags, - count_non_255_bytes(afl, afl->virgin_bits), tags, - afl->var_byte_count, tags, afl->expand_havoc); + snprintf( + buff, bufflen, afl->statsd_metric_format, tags, + afl->queue_cycle ? (afl->queue_cycle - 1) : 0, tags, + afl->cycles_wo_finds, tags, afl->fsrv.total_execs, tags, + afl->fsrv.total_execs / + ((double)(get_cur_time() + afl->prev_run_time - afl->start_time) / + 1000), + tags, afl->queued_paths, tags, afl->queued_favored, tags, + afl->queued_discovered, tags, afl->queued_imported, tags, + afl->max_depth, tags, afl->current_entry, tags, afl->pending_favored, + tags, afl->pending_not_fuzzed, tags, afl->queued_variable, tags, + afl->unique_crashes, tags, afl->unique_hangs, tags, afl->total_crashes, + tags, afl->slowest_exec_ms, tags, + count_non_255_bytes(afl, afl->virgin_bits), tags, afl->var_byte_count, + tags, afl->expand_havoc); } -- cgit v1.2.3 From 0ad56167c53ae660d40ccc6cdedb39f0a52eefcd Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 7 Feb 2021 07:51:29 +0100 Subject: fix scan-build issues --- src/afl-cc.c | 7 ------- src/afl-fuzz-init.c | 2 +- src/afl-fuzz-redqueen.c | 36 +++++++++++++++++++++++++++++++----- 3 files changed, 32 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 76f4a437..0ae401e7 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -315,16 +315,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0, shared_linking = 0, preprocessor_only = 0, have_unroll = 0, have_o = 0, have_pic = 0, have_c = 0; - u8 *name; cc_params = ck_alloc((argc + 128) * sizeof(u8 *)); - name = strrchr(argv[0], '/'); - if (!name) - name = argv[0]; - else - ++name; - if (lto_mode) { if (lto_flag[0] != '-') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 40ba20c7..702e732d 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1242,7 +1242,7 @@ static void link_or_copy(u8 *old_path, u8 *new_path) { void pivot_inputs(afl_state_t *afl) { - struct queue_entry *q = afl->queue; + struct queue_entry *q; u32 id = 0, i; ACTF("Creating hard links for all input files..."); diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index f619a6d3..002929c5 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -1415,7 +1415,7 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { } else if (b[k] == 0xff) { - ++cons_0; + ++cons_ff; } else { @@ -1473,7 +1473,7 @@ static void try_to_add_to_dictN(afl_state_t *afl, u128 v, u8 size) { } else if (b[k] == 0xff) { - ++cons_0; + ++cons_ff; } else { @@ -2410,7 +2410,21 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { // manually clear the full cmp_map memset(afl->shm.cmp_map, 0, sizeof(struct cmp_map)); - if (unlikely(common_fuzz_cmplog_stuff(afl, orig_buf, len))) { return 1; } + if (unlikely(common_fuzz_cmplog_stuff(afl, orig_buf, len))) { + + afl->queue_cur->colorized = CMPLOG_LVL_MAX; + while (taint) { + + t = taint->next; + ck_free(taint); + taint = t; + + } + + return 1; + + } + if (unlikely(!afl->orig_cmp_map)) { afl->orig_cmp_map = ck_alloc_nozero(sizeof(struct cmp_map)); @@ -2419,7 +2433,20 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { memcpy(afl->orig_cmp_map, afl->shm.cmp_map, sizeof(struct cmp_map)); memset(afl->shm.cmp_map->headers, 0, sizeof(struct cmp_header) * CMP_MAP_W); - if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) { return 1; } + if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) { + + afl->queue_cur->colorized = CMPLOG_LVL_MAX; + while (taint) { + + t = taint->next; + ck_free(taint); + taint = t; + + } + + return 1; + + } #ifdef _DEBUG dump("ORIG", orig_buf, len); @@ -2530,7 +2557,6 @@ exit_its: afl->queue_cur->colorized = CMPLOG_LVL_MAX; ck_free(afl->queue_cur->cmplog_colorinput); - t = taint; while (taint) { t = taint->next; -- cgit v1.2.3 From 17cbb03ba7d4fc0eb3b3b47911c58e25b567e89b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 9 Feb 2021 09:18:24 +0100 Subject: more cmplog options in config.h --- src/afl-fuzz-redqueen.c | 56 ++++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 002929c5..7844eedf 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -30,8 +30,7 @@ //#define _DEBUG //#define CMPLOG_INTROSPECTION -#define COMBINE -#define ARITHMETIC_LESSER_GREATER +#define CMPLOG_COMBINE // CMP attribute enum enum { @@ -496,7 +495,7 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) { } -#ifdef CMPLOG_TRANSFORM +#ifdef CMPLOG_SOLVE_TRANSFORM static int strntoll(const char *str, size_t sz, char **end, int base, long long *out) { @@ -577,7 +576,7 @@ static int is_hex(const char *str) { } - #ifdef CMPLOG_TRANSFORM_BASE64 + #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 // tests 4 bytes at location static int is_base64(const char *str) { @@ -717,7 +716,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // o_pattern, pattern, repl, changed_val, idx, taint_len, // h->shape + 1, attr); -#ifdef CMPLOG_TRANSFORM +#ifdef CMPLOG_SOLVE_TRANSFORM // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3 if (lvl & LVL3) { @@ -1009,7 +1008,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u64 tmp_64 = *buf_64; *buf_64 = repl; if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } -#ifdef COMBINE +#ifdef CMPLOG_COMBINE if (*status == 1) { memcpy(cbuf + idx, buf_64, 8); } #endif *buf_64 = tmp_64; @@ -1050,7 +1049,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u32 tmp_32 = *buf_32; *buf_32 = (u32)repl; if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } -#ifdef COMBINE +#ifdef CMPLOG_COMBINE if (*status == 1) { memcpy(cbuf + idx, buf_32, 4); } #endif *buf_32 = tmp_32; @@ -1084,7 +1083,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u16 tmp_16 = *buf_16; *buf_16 = (u16)repl; if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } -#ifdef COMBINE +#ifdef CMPLOG_COMBINE if (*status == 1) { memcpy(cbuf + idx, buf_16, 2); } #endif *buf_16 = tmp_16; @@ -1122,7 +1121,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u8 tmp_8 = *buf_8; *buf_8 = (u8)repl; if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } -#ifdef COMBINE +#ifdef CMPLOG_COMBINE if (*status == 1) { cbuf[idx] = *buf_8; } #endif *buf_8 = tmp_8; @@ -1139,7 +1138,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // 16 = modified float, 32 = modified integer (modified = wont match // in original buffer) -#ifdef ARITHMETIC_LESSER_GREATER +#ifdef CMPLOG_SOLVE_ARITHMETIC if (lvl < LVL3 || attr == IS_TRANSFORM) { return 0; } if (!(attr & (IS_GREATER | IS_LESSER)) || SHAPE_BYTES(h->shape) < 4) { @@ -1304,7 +1303,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } -#endif /* ARITHMETIC_LESSER_GREATER */ +#endif /* CMPLOG_SOLVE_ARITHMETIC */ return 0; @@ -1366,7 +1365,7 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h, if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } - #ifdef COMBINE + #ifdef CMPLOG_COMBINE if (*status == 1) { memcpy(cbuf + idx, r, shape); } #endif @@ -1774,10 +1773,10 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, u32 taint_len, u8 *orig_buf, u8 *buf, u8 *cbuf, u32 len, u8 lvl, u8 *status) { -#ifndef COMBINE +#ifndef CMPLOG_COMBINE (void)(cbuf); #endif -#ifndef CMPLOG_TRANSFORM +#ifndef CMPLOG_SOLVE_TRANSFORM (void)(changed_val); #endif @@ -1847,7 +1846,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } -#ifdef COMBINE +#ifdef CMPLOG_COMBINE if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i); } #endif @@ -1859,14 +1858,14 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } -#ifdef CMPLOG_TRANSFORM +#ifdef CMPLOG_SOLVE_TRANSFORM if (*status == 1) return 0; if (lvl & LVL3) { u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, fromhex = 0; - #ifdef CMPLOG_TRANSFORM_BASE64 + #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 u32 tob64 = 0, fromb64 = 0; #endif u32 from_0 = 0, from_x = 0, from_X = 0, from_slash = 0, from_up = 0; @@ -1964,7 +1963,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - #ifdef CMPLOG_TRANSFORM_BASE64 + #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 if (i % 3 == 2 && i < 24) { if (is_base64(repl + ((i / 3) << 2))) tob64 += 3; @@ -2012,13 +2011,13 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, "from_0=%u from_slash=%u from_x=%u\n", idx, i, xor, arith, tolower, toupper, tohex, fromhex, to_0, to_slash, to_x, from_0, from_slash, from_x); - #ifdef CMPLOG_TRANSFORM_BASE64 + #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 fprintf(stderr, "RTN idx=%u loop=%u tob64=%u from64=%u\n", tob64, fromb64); #endif #endif - #ifdef CMPLOG_TRANSFORM_BASE64 + #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 // input is base64 and converted to binary? convert repl to base64! if ((i % 4) == 3 && i < 24 && fromb64 > i) { @@ -2170,14 +2169,14 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - #ifdef COMBINE + #ifdef CMPLOG_COMBINE if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i + 1); } #endif if ((i >= 7 && (i >= xor&&i >= arith &&i >= tolower &&i >= toupper &&i > tohex &&i > (fromhex + from_0 + from_x + from_slash + 1) - #ifdef CMPLOG_TRANSFORM_BASE64 + #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 && i > tob64 + 3 && i > fromb64 + 4 #endif )) || @@ -2469,7 +2468,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { u32 lvl = (afl->queue_cur->colorized ? 0 : LVL1) + (afl->cmplog_lvl == CMPLOG_LVL_MAX ? LVL3 : 0); -#ifdef COMBINE +#ifdef CMPLOG_COMBINE u8 *cbuf = afl_realloc((void **)&afl->in_scratch_buf, len + 128); memcpy(cbuf, orig_buf, len); u8 *virgin_backup = afl_realloc((void **)&afl->ex_buf, afl->shm.map_size); @@ -2526,7 +2525,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } else if ((lvl & LVL1) -#ifdef CMPLOG_TRANSFORM +#ifdef CMPLOG_SOLVE_TRANSFORM || (lvl & LVL3) #endif ) { @@ -2583,7 +2582,7 @@ exit_its: } -#ifdef COMBINE +#ifdef CMPLOG_COMBINE if (afl->queued_paths + afl->unique_crashes > orig_hit_cnt + 1) { // copy the current virgin bits so we can recover the information @@ -2622,7 +2621,7 @@ exit_its: dump("COMB", cbuf, len); if (status == 1) { - fprintf(stderr, "NEW COMBINED\n"); + fprintf(stderr, "NEW CMPLOG_COMBINED\n"); } else { @@ -2671,8 +2670,3 @@ exit_its: return r; } - -#ifdef COMBINE - #undef COMBINE -#endif - -- cgit v1.2.3 From 22a3c7f7d043d9dbf39c847061d88a4577537031 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Fri, 12 Feb 2021 09:42:22 +0100 Subject: fix #736 (ty b1gr3db) --- src/afl-fuzz-redqueen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 7844eedf..3ce4148d 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -1303,7 +1303,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } -#endif /* CMPLOG_SOLVE_ARITHMETIC */ +#endif /* CMPLOG_SOLVE_ARITHMETIC */ return 0; @@ -2670,3 +2670,4 @@ exit_its: return r; } + -- cgit v1.2.3 From 1ba5d1008e749a12ac338f57adbac3b2b4cf9ea9 Mon Sep 17 00:00:00 2001 From: aflpp Date: Sat, 13 Feb 2021 10:53:40 +0100 Subject: fuck you llvm 13 --- src/afl-cc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 0ae401e7..9d88f262 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -554,6 +554,11 @@ static void edit_params(u32 argc, char **argv, char **envp) { } +#if LLVM_MAJOR >= 13 + // fuck you llvm 13 + cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager"; +#endif + if (lto_mode && !have_c) { u8 *ld_path = strdup(AFL_REAL_LD); -- cgit v1.2.3 From 385312c65858695b55607ccd376fb5ea8f83a688 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 13 Feb 2021 13:31:17 +0100 Subject: fix issue #732 afl-cmin and afl-showmap should support '-f' --- src/afl-showmap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index c424cdf3..2e421065 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1013,7 +1013,6 @@ int main(int argc, char **argv_orig, char **envp) { if (in_dir) { - if (at_file) { PFATAL("Options -A and -i are mutually exclusive"); } detect_file_args(argv + optind, "", &fsrv->use_stdin); } else { @@ -1169,7 +1168,7 @@ int main(int argc, char **argv_orig, char **envp) { } - stdin_file = + stdin_file = at_file ? strdup(at_file) : alloc_printf("%s/.afl-showmap-temp-%u", use_dir, (u32)getpid()); unlink(stdin_file); atexit(at_exit_handler); -- cgit v1.2.3 From 1d60c39191478334e27ddf4f60cf9b27710502f0 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 13 Feb 2021 13:42:37 +0100 Subject: fix new compiler warning --- src/afl-showmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 2e421065..0d2c5ceb 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1168,7 +1168,7 @@ int main(int argc, char **argv_orig, char **envp) { } - stdin_file = at_file ? strdup(at_file) : + stdin_file = at_file ? strdup(at_file) : (char *) alloc_printf("%s/.afl-showmap-temp-%u", use_dir, (u32)getpid()); unlink(stdin_file); atexit(at_exit_handler); -- cgit v1.2.3 From 9bd1e19d7f004b4da6a610b07e59f99d66bb7ec2 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 13 Feb 2021 22:43:56 +0100 Subject: added AFL_IGNORE_UNKNOWN_ENVS --- src/afl-cc.c | 1 + src/afl-common.c | 4 ++-- src/afl-fuzz.c | 1 + src/afl-showmap.c | 5 +++-- 4 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 9d88f262..d41f79a2 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1587,6 +1587,7 @@ int main(int argc, char **argv, char **envp) { "libtokencap.so)\n" " AFL_PATH: path to instrumenting pass and runtime " "(afl-compiler-rt.*o)\n" + " AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n" " AFL_INST_RATIO: percentage of branches to instrument\n" " AFL_QUIET: suppress verbose output\n" " AFL_HARDEN: adds code hardening to catch memory bugs\n" diff --git a/src/afl-common.c b/src/afl-common.c index 1cc7f462..589aac71 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -523,7 +523,7 @@ void check_environment_vars(char **envp) { if (be_quiet) { return; } int index = 0, issue_detected = 0; - char *env, *val; + char *env, *val, *ignore = getenv("AFL_IGNORE_UNKNOWN_ENVS"); while ((env = envp[index++]) != NULL) { if (strncmp(env, "ALF_", 4) == 0 || strncmp(env, "_ALF", 4) == 0 || @@ -582,7 +582,7 @@ void check_environment_vars(char **envp) { } - if (match == 0) { + if (match == 0 && !ignore) { WARNF("Mistyped AFL environment variable: %s", env); issue_detected = 1; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e4139857..e0ac8840 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -198,6 +198,7 @@ static void usage(u8 *argv0, int more_help) { "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n" "AFL_HANG_TMOUT: override timeout value (in milliseconds)\n" "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n" + "AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n" "AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n" "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n" "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n" diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 0d2c5ceb..b40527d3 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1168,8 +1168,9 @@ int main(int argc, char **argv_orig, char **envp) { } - stdin_file = at_file ? strdup(at_file) : (char *) - alloc_printf("%s/.afl-showmap-temp-%u", use_dir, (u32)getpid()); + stdin_file = at_file ? strdup(at_file) + : (char *)alloc_printf("%s/.afl-showmap-temp-%u", + use_dir, (u32)getpid()); unlink(stdin_file); atexit(at_exit_handler); fsrv->out_file = stdin_file; -- cgit v1.2.3 From f31d8b8401f7bebb75a19e27c21143c31ad33448 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Mon, 15 Feb 2021 08:46:19 +0100 Subject: redqueen fix compiler warnings for 32 bit --- src/afl-fuzz-redqueen.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 3ce4148d..527feef5 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -1498,11 +1498,12 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, struct cmp_header *h = &afl->shm.cmp_map->headers[key]; struct tainted * t; u32 i, j, idx, taint_len, loggeds; - u32 have_taint = 1, is_n = 0; + u32 have_taint = 1; u8 status = 0, found_one = 0; /* loop cmps are useless, detect and ignore them */ #ifdef WORD_SIZE_64 + u32 is_n = 0; u128 s128_v0 = 0, s128_v1 = 0, orig_s128_v0 = 0, orig_s128_v1 = 0; #endif u64 s_v0, s_v1; @@ -1520,6 +1521,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } +#ifdef WORD_SIZE_64 switch (SHAPE_BYTES(h->shape)) { case 1: @@ -1531,6 +1533,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, is_n = 1; } +#endif for (i = 0; i < loggeds; ++i) { @@ -2606,8 +2609,8 @@ exit_its: } #else - u32 *v = (u64 *)afl->virgin_bits; - u32 *s = (u64 *)virgin_save; + u32 *v = (u32 *)afl->virgin_bits; + u32 *s = (u32 *)virgin_save; u32 i; for (i = 0; i < (afl->shm.map_size >> 2); i++) { -- cgit v1.2.3 From e3a5c31307f323452dc4b5288e0d19a02b596a33 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 15 Feb 2021 13:25:15 +0100 Subject: llvm bug workaround for lto extint --- src/afl-cc.c | 2 ++ src/afl-fuzz-redqueen.c | 1 + 2 files changed, 3 insertions(+) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index d41f79a2..959c9a6f 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1875,6 +1875,8 @@ int main(int argc, char **argv, char **envp) { edit_params(argc, argv, envp); + if (lto_mode) { setenv("_AFL_LTO_COMPILE", "1", 1); } + if (debug) { DEBUGF("cd '%s';", getthecwd()); diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 527feef5..2b01ecad 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -1533,6 +1533,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, is_n = 1; } + #endif for (i = 0; i < loggeds; ++i) { -- cgit v1.2.3 From 512f53984cd53d75900e6648720ef7cc7c571ca1 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Mon, 15 Feb 2021 13:51:32 +0100 Subject: fixed scan-build issues --- src/afl-fuzz-redqueen.c | 17 ++++++++++++++++- src/afl-fuzz.c | 15 ++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 7844eedf..deaddc56 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -382,6 +382,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, rng = ranges; ranges = rng->next; ck_free(rng); + rng = NULL; } @@ -455,6 +456,15 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, return 0; checksum_fail: + while (ranges) { + + rng = ranges; + ranges = rng->next; + ck_free(rng); + rng = NULL; + + } + ck_free(backup); ck_free(changed); @@ -503,6 +513,8 @@ static int strntoll(const char *str, size_t sz, char **end, int base, long long ret; const char *beg = str; + if (!str || !sz) { return 1; } + for (; beg && sz && *beg == ' '; beg++, sz--) {}; if (!sz) return 1; @@ -526,6 +538,8 @@ static int strntoull(const char *str, size_t sz, char **end, int base, unsigned long long ret; const char * beg = str; + if (!str || !sz) { return 1; } + for (; beg && sz && *beg == ' '; beg++, sz--) ; @@ -1303,7 +1317,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } -#endif /* CMPLOG_SOLVE_ARITHMETIC */ +#endif /* CMPLOG_SOLVE_ARITHMETIC */ return 0; @@ -2670,3 +2684,4 @@ exit_its: return r; } + diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e4139857..e79671e0 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -552,13 +552,22 @@ int main(int argc, char **argv_orig, char **envp) { case 'F': /* foreign sync dir */ - if (!afl->is_main_node) + if (!optarg) { FATAL("Missing path for -F"); } + if (!afl->is_main_node) { + FATAL( "Option -F can only be specified after the -M option for the " "main fuzzer of a fuzzing campaign"); - if (afl->foreign_sync_cnt >= FOREIGN_SYNCS_MAX) + + } + + if (afl->foreign_sync_cnt >= FOREIGN_SYNCS_MAX) { + FATAL("Maximum %u entried of -F option can be specified", FOREIGN_SYNCS_MAX); + + } + afl->foreign_syncs[afl->foreign_sync_cnt].dir = optarg; while (afl->foreign_syncs[afl->foreign_sync_cnt] .dir[strlen(afl->foreign_syncs[afl->foreign_sync_cnt].dir) - @@ -802,7 +811,7 @@ int main(int argc, char **argv_orig, char **envp) { case 'l': { - afl->cmplog_lvl = atoi(optarg); + if (optarg) { afl->cmplog_lvl = atoi(optarg); } if (afl->cmplog_lvl < 1 || afl->cmplog_lvl > CMPLOG_LVL_MAX) { FATAL( -- cgit v1.2.3 From 6caec2169cef890ba8a62715c2c26cc0608626e3 Mon Sep 17 00:00:00 2001 From: Michael Rodler Date: Mon, 15 Feb 2021 19:14:28 +0100 Subject: Revert "llvm bug workaround for lto extint" This reverts commit e3a5c31307f323452dc4b5288e0d19a02b596a33. --- src/afl-cc.c | 2 -- src/afl-fuzz-redqueen.c | 1 - 2 files changed, 3 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 959c9a6f..d41f79a2 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1875,8 +1875,6 @@ int main(int argc, char **argv, char **envp) { edit_params(argc, argv, envp); - if (lto_mode) { setenv("_AFL_LTO_COMPILE", "1", 1); } - if (debug) { DEBUGF("cd '%s';", getthecwd()); diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index cf65d3c1..275af9c8 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -1547,7 +1547,6 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, is_n = 1; } - #endif for (i = 0; i < loggeds; ++i) { -- cgit v1.2.3 From 4c47b242eb976b8518ab8884733d02465f02d90a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 17 Feb 2021 17:40:01 +0100 Subject: fix FPE in colorization --- src/afl-fuzz-redqueen.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 275af9c8..bbe35fe5 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -421,8 +421,9 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, if (taint) { - if (len / positions == 1 && positions > CMPLOG_POSITIONS_MAX && - afl->active_paths / afl->colorize_success > CMPLOG_CORPUS_PERCENT) { + if (afl->colorize_success && + (len / positions == 1 && positions > CMPLOG_POSITIONS_MAX && + afl->active_paths / afl->colorize_success > CMPLOG_CORPUS_PERCENT)) { #ifdef _DEBUG fprintf(stderr, "Colorization unsatisfactory\n"); @@ -1547,6 +1548,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, is_n = 1; } + #endif for (i = 0; i < loggeds; ++i) { -- cgit v1.2.3 From 5dd35f5281afec0955c08fe9f99e3c83222b7764 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 17 Feb 2021 19:10:05 +0100 Subject: fix a rare i2s illegal memory access --- src/afl-fuzz-redqueen.c | 71 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index bbe35fe5..3ac7ba11 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -808,37 +808,82 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // Try to identify transform magic if (pattern != o_pattern && repl == changed_val && attr <= IS_EQUAL) { - u64 *ptr = (u64 *)&buf[idx]; - u64 *o_ptr = (u64 *)&orig_buf[idx]; - u64 b_val, o_b_val, mask; + u64 b_val, o_b_val, mask; + u8 bytes; switch (SHAPE_BYTES(h->shape)) { case 0: case 1: - b_val = (u64)(*ptr % 0x100); + bytes = 1; + break; + case 2: + bytes = 2; + break; + case 3: + case 4: + bytes = 4; + break; + default: + bytes = 8; + + } + + // necessary for preventing heap access overflow + bytes = MIN(bytes, len - idx); + + switch (bytes) { + + case 0: // cannot happen + b_val = o_b_val = mask = 0; // keep the linters happy + break; + case 1: { + + u8 *ptr = (u8 *)&buf[idx]; + u8 *o_ptr = (u8 *)&orig_buf[idx]; + b_val = (u64)(*ptr); o_b_val = (u64)(*o_ptr % 0x100); mask = 0xff; break; + + } + case 2: - case 3: - b_val = (u64)(*ptr % 0x10000); - o_b_val = (u64)(*o_ptr % 0x10000); + case 3: { + + u16 *ptr = (u16 *)&buf[idx]; + u16 *o_ptr = (u16 *)&orig_buf[idx]; + b_val = (u64)(*ptr); + o_b_val = (u64)(*o_ptr); mask = 0xffff; break; + + } + case 4: case 5: case 6: - case 7: - b_val = (u64)(*ptr % 0x100000000); - o_b_val = (u64)(*o_ptr % 0x100000000); + case 7: { + + u32 *ptr = (u32 *)&buf[idx]; + u32 *o_ptr = (u32 *)&orig_buf[idx]; + b_val = (u64)(*ptr); + o_b_val = (u64)(*o_ptr); mask = 0xffffffff; break; - default: - b_val = *ptr; - o_b_val = *o_ptr; + + } + + default: { + + u64 *ptr = (u64 *)&buf[idx]; + u64 *o_ptr = (u64 *)&orig_buf[idx]; + b_val = (u64)(*ptr); + o_b_val = (u64)(*o_ptr); mask = 0xffffffffffffffff; + } + } // test for arithmetic, eg. "if ((user_val - 0x1111) == 0x1234) ..." -- cgit v1.2.3 From 89cf94f0e6afd4d360f7f139f16a6730a07b478d Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Fri, 19 Feb 2021 20:33:12 +0100 Subject: suggested env vars for lazy ppl --- src/afl-common.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/afl-fuzz-state.c | 2 + 2 files changed, 118 insertions(+) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 589aac71..0b38b222 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -518,6 +518,120 @@ int parse_afl_kill_signal_env(u8 *afl_kill_signal_env, int default_signal) { } +#define HELPER_MIN3(a, b, c) \ + ((a) < (b) ? ((a) < (c) ? (a) : (c)) : ((b) < (c) ? (b) : (c))) + +// from +// https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#C +static int string_distance_levenshtein(char *s1, char *s2) { + + unsigned int s1len, s2len, x, y, lastdiag, olddiag; + s1len = strlen(s1); + s2len = strlen(s2); + unsigned int column[s1len + 1]; + for (y = 1; y <= s1len; y++) + column[y] = y; + for (x = 1; x <= s2len; x++) { + + column[0] = x; + for (y = 1, lastdiag = x - 1; y <= s1len; y++) { + + olddiag = column[y]; + column[y] = HELPER_MIN3(column[y] + 1, column[y - 1] + 1, + lastdiag + (s1[y - 1] == s2[x - 1] ? 0 : 1)); + lastdiag = olddiag; + + } + + } + + return column[s1len]; + +} + +#undef HELPER_MIN3 + +void print_suggested_envs(char *mispelled_env) { + + size_t env_name_len = + strcspn(mispelled_env, "=") - 4; // remove the AFL_prefix + char *env_name = ck_alloc(env_name_len + 1); + memcpy(env_name, mispelled_env + 4, env_name_len); + + char *seen = ck_alloc(sizeof(afl_environment_variables) / sizeof(char *)); + + int j; + for (j = 0; afl_environment_variables[j] != NULL; ++j) { + + char *afl_env = afl_environment_variables[j] + 4; + + int distance = string_distance_levenshtein(afl_env, env_name); + if (distance <= 3 && seen[j] == 0) { + + SAYF("Did you mean %s?\n", afl_environment_variables[j]); + seen[j] = 1; + + } + + size_t afl_env_len = strlen(afl_env); + char * reduced = ck_alloc(afl_env_len + 1); + + size_t start = 0; + while (start < afl_env_len) { + + size_t end = start + strcspn(afl_env + start, "_") + 1; + memcpy(reduced, afl_env, start); + if (end < afl_env_len) + memcpy(reduced + start, afl_env + end, afl_env_len - end); + reduced[afl_env_len - end + start] = 0; + + int distance = string_distance_levenshtein(reduced, env_name); + if (distance <= 3 && seen[j] == 0) { + + SAYF("Did you mean %s?\n", afl_environment_variables[j]); + seen[j] = 1; + + } + + start = end; + + }; + + } + + char * reduced = ck_alloc(env_name_len + 1); + size_t start = 0; + while (start < env_name_len) { + + size_t end = start + strcspn(env_name + start, "_") + 1; + memcpy(reduced, env_name, start); + if (end < env_name_len) + memcpy(reduced + start, env_name + end, env_name_len - end); + reduced[env_name_len - end + start] = 0; + + for (j = 0; afl_environment_variables[j] != NULL; ++j) { + + int distance = string_distance_levenshtein( + afl_environment_variables[j] + 4, reduced); + if (distance <= 3 && seen[j] == 0) { + + SAYF("Did you mean %s?\n", afl_environment_variables[j]); + seen[j] = 1; + + } + + } + + start = end; + + }; + + ck_free(env_name); + ck_free(reduced); + ck_free(seen); + +} + void check_environment_vars(char **envp) { if (be_quiet) { return; } @@ -587,6 +701,8 @@ void check_environment_vars(char **envp) { WARNF("Mistyped AFL environment variable: %s", env); issue_detected = 1; + print_suggested_envs(env); + } } diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 5040e3ef..3d36e712 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -486,6 +486,8 @@ void read_afl_environment(afl_state_t *afl, char **envp) { WARNF("Mistyped AFL environment variable: %s", env); issue_detected = 1; + print_suggested_envs(env); + } } -- cgit v1.2.3 From 62767a42dc2101a67eeb723ca94f5bf853525d60 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Fri, 19 Feb 2021 20:40:38 +0100 Subject: improved env suggestions --- src/afl-common.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 0b38b222..531753c2 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -551,6 +551,8 @@ static int string_distance_levenshtein(char *s1, char *s2) { #undef HELPER_MIN3 +#define ENV_SIMILARITY_TRESHOLD 3 + void print_suggested_envs(char *mispelled_env) { size_t env_name_len = @@ -559,20 +561,28 @@ void print_suggested_envs(char *mispelled_env) { memcpy(env_name, mispelled_env + 4, env_name_len); char *seen = ck_alloc(sizeof(afl_environment_variables) / sizeof(char *)); + int found = 0; int j; for (j = 0; afl_environment_variables[j] != NULL; ++j) { char *afl_env = afl_environment_variables[j] + 4; - int distance = string_distance_levenshtein(afl_env, env_name); - if (distance <= 3 && seen[j] == 0) { + if (distance < ENV_SIMILARITY_TRESHOLD && seen[j] == 0) { SAYF("Did you mean %s?\n", afl_environment_variables[j]); seen[j] = 1; + found = 1; } + + } + + if (found) goto cleanup; + + for (j = 0; afl_environment_variables[j] != NULL; ++j) { + char *afl_env = afl_environment_variables[j] + 4; size_t afl_env_len = strlen(afl_env); char * reduced = ck_alloc(afl_env_len + 1); @@ -586,10 +596,11 @@ void print_suggested_envs(char *mispelled_env) { reduced[afl_env_len - end + start] = 0; int distance = string_distance_levenshtein(reduced, env_name); - if (distance <= 3 && seen[j] == 0) { + if (distance < ENV_SIMILARITY_TRESHOLD && seen[j] == 0) { SAYF("Did you mean %s?\n", afl_environment_variables[j]); seen[j] = 1; + found = 1; } @@ -599,6 +610,8 @@ void print_suggested_envs(char *mispelled_env) { } + if (found) goto cleanup; + char * reduced = ck_alloc(env_name_len + 1); size_t start = 0; while (start < env_name_len) { @@ -613,7 +626,7 @@ void print_suggested_envs(char *mispelled_env) { int distance = string_distance_levenshtein( afl_environment_variables[j] + 4, reduced); - if (distance <= 3 && seen[j] == 0) { + if (distance < ENV_SIMILARITY_TRESHOLD && seen[j] == 0) { SAYF("Did you mean %s?\n", afl_environment_variables[j]); seen[j] = 1; @@ -626,8 +639,10 @@ void print_suggested_envs(char *mispelled_env) { }; - ck_free(env_name); ck_free(reduced); + +cleanup: + ck_free(env_name); ck_free(seen); } -- cgit v1.2.3 From 100aac4dd39012750036b2fd71eed5b21959f693 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 20 Feb 2021 14:15:38 +0100 Subject: -t help --- src/afl-fuzz.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 8eb3625b..e3e9007d 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -103,7 +103,8 @@ static void usage(u8 *argv0, int more_help) { " quad -- see docs/power_schedules.md\n" " -f file - location read by the fuzzed program (default: stdin " "or @@)\n" - " -t msec - timeout for each run (auto-scaled, 50-%u ms)\n" + " -t msec - timeout for each run (auto-scaled, 50-... ms, default %u ms)\n" + " add a '+' to skip over seeds running longer.\n" " -m megs - memory limit for child process (%u MB, 0 = no limit " "[default])\n" " -Q - use binary-only instrumentation (QEMU mode)\n" -- cgit v1.2.3 From b957218a3aad95af02a4da8207c7dabb893d4dc8 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 21 Feb 2021 11:29:54 +0100 Subject: more attuned colorize repace --- src/afl-fuzz-redqueen.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 3ac7ba11..d77baf25 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -205,14 +205,31 @@ static void type_replace(afl_state_t *afl, u8 *buf, u32 len) { case '\t': c = ' '; break; - /* - case '\r': - case '\n': - // nothing ... - break; - */ + case '\r': + c = '\n'; + break; + case '\n': + c = '\r'; + break; + case 0: + c = 1; + break; + case 1: + c = 0; + break; + case 0xff: + c = 0; + break; default: - c = (buf[i] ^ 0xff); + if (buf[i] < 32) { + + c = (buf[i] ^ 0x1f); + + } else { + + c = (buf[i] ^ 0x7f); // we keep the highest bit + + } } -- cgit v1.2.3 From 974aab6cf6aa4ae34ee73bdceed1bd44a212fc5e Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 21 Feb 2021 17:53:09 +0100 Subject: cmplog config.h -> -l option --- src/afl-common.c | 8 ++--- src/afl-fuzz-redqueen.c | 83 +++++++++++++++++++++++++------------------------ src/afl-fuzz.c | 46 ++++++++++++++++++++------- 3 files changed, 82 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 531753c2..ce63c262 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -561,13 +561,13 @@ void print_suggested_envs(char *mispelled_env) { memcpy(env_name, mispelled_env + 4, env_name_len); char *seen = ck_alloc(sizeof(afl_environment_variables) / sizeof(char *)); - int found = 0; + int found = 0; int j; for (j = 0; afl_environment_variables[j] != NULL; ++j) { char *afl_env = afl_environment_variables[j] + 4; - int distance = string_distance_levenshtein(afl_env, env_name); + int distance = string_distance_levenshtein(afl_env, env_name); if (distance < ENV_SIMILARITY_TRESHOLD && seen[j] == 0) { SAYF("Did you mean %s?\n", afl_environment_variables[j]); @@ -575,14 +575,14 @@ void print_suggested_envs(char *mispelled_env) { found = 1; } - + } if (found) goto cleanup; for (j = 0; afl_environment_variables[j] != NULL; ++j) { - char *afl_env = afl_environment_variables[j] + 4; + char * afl_env = afl_environment_variables[j] + 4; size_t afl_env_len = strlen(afl_env); char * reduced = ck_alloc(afl_env_len + 1); diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index d77baf25..1ab5f996 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -30,7 +30,6 @@ //#define _DEBUG //#define CMPLOG_INTROSPECTION -#define CMPLOG_COMBINE // CMP attribute enum enum { @@ -523,7 +522,7 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) { } -#ifdef CMPLOG_SOLVE_TRANSFORM +//#ifdef CMPLOG_SOLVE_TRANSFORM static int strntoll(const char *str, size_t sz, char **end, int base, long long *out) { @@ -608,7 +607,7 @@ static int is_hex(const char *str) { } - #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 +#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 // tests 4 bytes at location static int is_base64(const char *str) { @@ -721,10 +720,10 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) { } - #endif - #endif +//#endif + static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u64 pattern, u64 repl, u64 o_pattern, u64 changed_val, u8 attr, u32 idx, u32 taint_len, @@ -748,9 +747,9 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // o_pattern, pattern, repl, changed_val, idx, taint_len, // h->shape + 1, attr); -#ifdef CMPLOG_SOLVE_TRANSFORM + //#ifdef CMPLOG_SOLVE_TRANSFORM // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3 - if (lvl & LVL3) { + if (afl->cmplog_enable_transform && (lvl & LVL3)) { u8 * endptr; u8 use_num = 0, use_unum = 0; @@ -771,11 +770,11 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - #ifdef _DEBUG +#ifdef _DEBUG if (idx == 0) fprintf(stderr, "ASCII is=%u use_num=%u use_unum=%u idx=%u %llx==%llx\n", afl->queue_cur->is_ascii, use_num, use_unum, idx, num, pattern); - #endif +#endif // num is likely not pattern as atoi("AAA") will be zero... if (use_num && ((u64)num == pattern || !num)) { @@ -1060,7 +1059,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } -#endif + //#endif // we only allow this for ascii2integer (above) so leave if this is the case if (unlikely(pattern == o_pattern)) { return 0; } @@ -1215,8 +1214,12 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // 16 = modified float, 32 = modified integer (modified = wont match // in original buffer) -#ifdef CMPLOG_SOLVE_ARITHMETIC - if (lvl < LVL3 || attr == IS_TRANSFORM) { return 0; } + //#ifdef CMPLOG_SOLVE_ARITHMETIC + if (!afl->cmplog_enable_arith || lvl < LVL3 || attr == IS_TRANSFORM) { + + return 0; + + } if (!(attr & (IS_GREATER | IS_LESSER)) || SHAPE_BYTES(h->shape) < 4) { @@ -1321,11 +1324,11 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, double *f = (double *)&repl; float g = (float)*f; repl_new = 0; - #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) memcpy((char *)&repl_new, (char *)&g, 4); - #else +#else memcpy(((char *)&repl_new) + 4, (char *)&g, 4); - #endif +#endif changed_val = repl_new; h->shape = 3; // modify shape @@ -1380,7 +1383,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } -#endif /* CMPLOG_SOLVE_ARITHMETIC */ + //#endif /* CMPLOG_SOLVE_ARITHMETIC return 0; @@ -1539,7 +1542,7 @@ static void try_to_add_to_dictN(afl_state_t *afl, u128 v, u8 size) { for (k = 0; k < size; ++k) { #else - u32 off = 16 - size; + u32 off = 16 - size; for (k = 16 - size; k < 16; ++k) { #endif @@ -1857,9 +1860,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, #ifndef CMPLOG_COMBINE (void)(cbuf); #endif -#ifndef CMPLOG_SOLVE_TRANSFORM - (void)(changed_val); -#endif + //#ifndef CMPLOG_SOLVE_TRANSFORM + // (void)(changed_val); + //#endif u8 save[40]; u32 saved_idx = idx, pre, from = 0, to = 0, i, j; @@ -1939,16 +1942,16 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } -#ifdef CMPLOG_SOLVE_TRANSFORM + //#ifdef CMPLOG_SOLVE_TRANSFORM if (*status == 1) return 0; - if (lvl & LVL3) { + if (afl->cmplog_enable_transform && (lvl & LVL3)) { u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, fromhex = 0; - #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 +#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 u32 tob64 = 0, fromb64 = 0; - #endif +#endif 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]; @@ -2044,7 +2047,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 +#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 if (i % 3 == 2 && i < 24) { if (is_base64(repl + ((i / 3) << 2))) tob64 += 3; @@ -2057,7 +2060,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - #endif +#endif if ((o_pattern[i] ^ orig_buf[idx + i]) == xor_val[i] && xor_val[i]) { @@ -2085,20 +2088,20 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - #ifdef _DEBUG +#ifdef _DEBUG fprintf(stderr, "RTN idx=%u loop=%u xor=%u arith=%u tolower=%u toupper=%u " "tohex=%u fromhex=%u to_0=%u to_slash=%u to_x=%u " "from_0=%u from_slash=%u from_x=%u\n", idx, i, xor, arith, tolower, toupper, tohex, fromhex, to_0, to_slash, to_x, from_0, from_slash, from_x); - #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 + #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 fprintf(stderr, "RTN idx=%u loop=%u tob64=%u from64=%u\n", tob64, fromb64); - #endif #endif +#endif - #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 +#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 // input is base64 and converted to binary? convert repl to base64! if ((i % 4) == 3 && i < 24 && fromb64 > i) { @@ -2121,7 +2124,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - #endif +#endif // input is converted to hex? convert repl to binary! if (i < 16 && tohex > i) { @@ -2250,16 +2253,16 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } - #ifdef CMPLOG_COMBINE +#ifdef CMPLOG_COMBINE if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i + 1); } - #endif +#endif if ((i >= 7 && (i >= xor&&i >= arith &&i >= tolower &&i >= toupper &&i > tohex &&i > (fromhex + from_0 + from_x + from_slash + 1) - #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 +#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 && i > tob64 + 3 && i > fromb64 + 4 - #endif +#endif )) || repl[i] != changed_val[i] || *status == 1) { @@ -2273,7 +2276,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, } -#endif + //#endif return 0; @@ -2606,9 +2609,9 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } else if ((lvl & LVL1) -#ifdef CMPLOG_SOLVE_TRANSFORM - || (lvl & LVL3) -#endif + //#ifdef CMPLOG_SOLVE_TRANSFORM + || ((lvl & LVL3) && afl->cmplog_enable_transform) + //#endif ) { if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, cbuf, len, lvl, taint))) { @@ -2689,7 +2692,7 @@ exit_its: #else u32 *v = (u32 *)afl->virgin_bits; u32 *s = (u32 *)virgin_save; - u32 i; + u32 i; for (i = 0; i < (afl->shm.map_size >> 2); i++) { v[i] &= s[i]; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e3e9007d..e2db029d 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -103,7 +103,8 @@ static void usage(u8 *argv0, int more_help) { " quad -- see docs/power_schedules.md\n" " -f file - location read by the fuzzed program (default: stdin " "or @@)\n" - " -t msec - timeout for each run (auto-scaled, 50-... ms, default %u ms)\n" + " -t msec - timeout for each run (auto-scaled, 50-... ms, default " + "%u ms)\n" " add a '+' to skip over seeds running longer.\n" " -m megs - memory limit for child process (%u MB, 0 = no limit " "[default])\n" @@ -123,10 +124,10 @@ static void usage(u8 *argv0, int more_help) { " -c program - enable CmpLog by specifying a binary compiled for " "it.\n" " if using QEMU, just use -c 0.\n" - " -l cmplog_level - set the complexity/intensivity of CmpLog.\n" - " Values: 1 (basic), 2 (larger files) and 3 " - "(transform)\n\n" - + " -l cmplog_opts - CmpLog configuration values (e.g. \"2AT\"):\n" + " 1=small files (default), 2=larger files, 3=all " + "files,\n" + " A=arithmetic solving, T=tranformational solving.\n\n" "Fuzzing behavior settings:\n" " -Z - sequential queue selection instead of weighted " "random\n" @@ -813,13 +814,36 @@ int main(int argc, char **argv_orig, char **envp) { case 'l': { - if (optarg) { afl->cmplog_lvl = atoi(optarg); } - if (afl->cmplog_lvl < 1 || afl->cmplog_lvl > CMPLOG_LVL_MAX) { + if (!optarg) { FATAL("missing parameter for 'l'"); } + char *c = optarg; + while (*c) { - FATAL( - "Bad complog level value, accepted values are 1 (default), 2 and " - "%u.", - CMPLOG_LVL_MAX); + switch (*c) { + + case '0': + case '1': + afl->cmplog_lvl = 1; + break; + case '2': + afl->cmplog_lvl = 2; + break; + case '3': + afl->cmplog_lvl = 3; + break; + case 'a': + case 'A': + afl->cmplog_enable_arith = 1; + break; + case 't': + case 'T': + afl->cmplog_enable_transform = 1; + break; + default: + FATAL("Unknown option value '%c' in -l %s", *c, optarg); + + } + + ++c; } -- cgit v1.2.3 From ac9cfd89dae0ce99df500793b3f5cbed2fd2e4f7 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 21 Feb 2021 23:27:07 +0100 Subject: how to compare afl++ --- src/afl-cc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index d41f79a2..a5e54691 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1699,7 +1699,9 @@ int main(int argc, char **argv, char **envp) { "Do not be overwhelmed :) afl-cc uses good defaults if no options are " "selected.\n" "Read the documentation for FEATURES though, all are good but few are " - "defaults.\n\n"); + "defaults.\n"); + "Recommended is afl-clang-lto with AFL_LLVM_CMPLOG or afl-clang-fast with\n" + "AFL_LLVM_CMPLOG and AFL_LLVM_DICT2FILE.\n\n" exit(1); -- cgit v1.2.3 From 8ad78f5b65d09375dddfa679ccce76bec0862c28 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 21 Feb 2021 23:42:08 +0100 Subject: fix --- src/afl-cc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index a5e54691..2eb8c575 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1699,9 +1699,9 @@ int main(int argc, char **argv, char **envp) { "Do not be overwhelmed :) afl-cc uses good defaults if no options are " "selected.\n" "Read the documentation for FEATURES though, all are good but few are " - "defaults.\n"); + "defaults.\n" "Recommended is afl-clang-lto with AFL_LLVM_CMPLOG or afl-clang-fast with\n" - "AFL_LLVM_CMPLOG and AFL_LLVM_DICT2FILE.\n\n" + "AFL_LLVM_CMPLOG and AFL_LLVM_DICT2FILE.\n\n"); exit(1); -- cgit v1.2.3 From 2785c8b197a1e7f109fa4dfb47fdd82eca0ad008 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 22 Feb 2021 12:34:37 +0100 Subject: crash fix --- src/afl-fuzz-init.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 702e732d..e372c803 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1060,13 +1060,22 @@ void perform_dry_run(afl_state_t *afl) { p->perf_score = 0; u32 i = 0; - while (unlikely(afl->queue_buf[i]->disabled)) { + while (unlikely(i < afl->queued_paths && afl->queue_buf[i] && + afl->queue_buf[i]->disabled)) { ++i; } - afl->queue = afl->queue_buf[i]; + if (i < afl->queued_paths && afl->queue_buf[i]) { + + afl->queue = afl->queue_buf[i]; + + } else { + + afl->queue = afl->queue_buf[0]; + + } afl->max_depth = 0; for (i = 0; i < afl->queued_paths; i++) { -- cgit v1.2.3 From a252943236b12c080248747bee06c9c5084b871e Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 22 Feb 2021 12:59:01 +0100 Subject: another fix for disabled entries --- src/afl-fuzz.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e2db029d..24d77cc9 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1770,12 +1770,15 @@ int main(int argc, char **argv_orig, char **envp) { if (unlikely(afl->old_seed_selection)) { afl->current_entry = 0; - while (unlikely(afl->queue_buf[afl->current_entry]->disabled)) { + while (unlikely(afl->current_entry < afl->queued_paths && + afl->queue_buf[afl->current_entry]->disabled)) { ++afl->current_entry; } + if (afl->current_entry >= afl->queued_paths) { afl->current_entry = 0; } + afl->queue_cur = afl->queue_buf[afl->current_entry]; if (unlikely(seek_to)) { -- cgit v1.2.3 From 70fe872940b9815698b4317bdde33da1dae27923 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 22 Feb 2021 16:39:38 +0100 Subject: ensure a valid seed exists --- src/afl-cc.c | 3 ++- src/afl-fuzz.c | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 2eb8c575..5f471355 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1700,7 +1700,8 @@ int main(int argc, char **argv, char **envp) { "selected.\n" "Read the documentation for FEATURES though, all are good but few are " "defaults.\n" - "Recommended is afl-clang-lto with AFL_LLVM_CMPLOG or afl-clang-fast with\n" + "Recommended is afl-clang-lto with AFL_LLVM_CMPLOG or afl-clang-fast " + "with\n" "AFL_LLVM_CMPLOG and AFL_LLVM_DICT2FILE.\n\n"); exit(1); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 24d77cc9..9137dc23 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1707,7 +1707,12 @@ int main(int argc, char **argv_orig, char **envp) { cull_queue(afl); - if (!afl->pending_not_fuzzed) { + // ensure we have at least one seed that is not disabled. + u32 entry, valid_seeds = 0; + for (entry = 0; entry < afl->queued_paths; ++entry) + if (!afl->queue_buf[entry]->disabled) { ++valid_seeds; } + + if (!afl->pending_not_fuzzed || !valid_seeds) { FATAL("We need at least one valid input seed that does not crash!"); -- cgit v1.2.3 From fb2a6b6941ffb6cf575d2a772c6e0d47b49835ee Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 22 Feb 2021 16:56:35 +0100 Subject: minimum sync time --- src/afl-fuzz-run.c | 2 ++ src/afl-fuzz.c | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 97cb7415..0b84a542 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -707,6 +707,8 @@ void sync_fuzzers(afl_state_t *afl) { if (afl->foreign_sync_cnt) read_foreign_testcases(afl, 0); + afl->last_sync_time = get_cur_time(); + } /* Trim all new test cases to save cycles when doing deterministic checks. The diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 9137dc23..f83aac9e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1986,15 +1986,24 @@ int main(int argc, char **argv_orig, char **envp) { if (unlikely(afl->is_main_node)) { - if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) { + if (unlikely(get_cur_time() > + (SYNC_TIME >> 1) + afl->last_sync_time)) { - sync_fuzzers(afl); + if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) { + + sync_fuzzers(afl); + + } } } else { - if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); } + if (unlikely(get_cur_time() > SYNC_TIME + afl->last_sync_time)) { + + if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); } + + } } -- cgit v1.2.3 From 7674dac1a16a9963e22eb628fdbd409befe19979 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 22 Feb 2021 18:17:35 +0100 Subject: auto mode for CTX + NGRAM --- src/afl-cc.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 5f471355..783cf23e 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1421,6 +1421,14 @@ int main(int argc, char **argv, char **envp) { } + if (instrument_opt_mode && instrument_mode == INSTRUMENT_DEFAULT && + (compiler_mode == LLVM || compiler_mode == UNSET)) { + + instrument_mode = INSTRUMENT_CLASSIC; + compiler_mode = LLVM; + + } + if (!compiler_mode) { // lto is not a default because outside of afl-cc RANLIB and AR have to -- cgit v1.2.3 From 745bc083d144a31981b3686d68bc34777758b359 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 22 Feb 2021 18:22:09 +0100 Subject: fix error msg --- src/afl-cc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 783cf23e..c3910e6d 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1802,8 +1802,8 @@ int main(int argc, char **argv, char **envp) { if (instrument_opt_mode && instrument_mode != INSTRUMENT_CLASSIC && instrument_mode != INSTRUMENT_CFG) FATAL( - "CTX and NGRAM instrumentation options can only be used with CFG " - "(recommended) and CLASSIC instrumentation modes!"); + "CTX and NGRAM instrumentation options can only be used with LLVM and " + "CFG or CLASSIC instrumentation modes!"); if (getenv("AFL_LLVM_SKIP_NEVERZERO") && getenv("AFL_LLVM_NOT_ZERO")) FATAL( -- cgit v1.2.3 From cc7c651dc97f5567af33164d396b390d36b46049 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 24 Feb 2021 18:07:08 +0100 Subject: tidied up env suggestions --- src/afl-common.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index ce63c262..1628e517 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -529,6 +529,8 @@ static int string_distance_levenshtein(char *s1, char *s2) { s1len = strlen(s1); s2len = strlen(s2); unsigned int column[s1len + 1]; + column[s1len] = 1; + for (y = 1; y <= s1len; y++) column[y] = y; for (x = 1; x <= s2len; x++) { @@ -608,6 +610,8 @@ void print_suggested_envs(char *mispelled_env) { }; + ck_free(reduced); + } if (found) goto cleanup; -- cgit v1.2.3 From 48a1a29baa49b633855f49536d72783d5a489b82 Mon Sep 17 00:00:00 2001 From: hexcoder Date: Wed, 24 Feb 2021 20:34:33 +0100 Subject: typos --- src/afl-fuzz.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index f83aac9e..d4e3958e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -127,7 +127,7 @@ static void usage(u8 *argv0, int more_help) { " -l cmplog_opts - CmpLog configuration values (e.g. \"2AT\"):\n" " 1=small files (default), 2=larger files, 3=all " "files,\n" - " A=arithmetic solving, T=tranformational solving.\n\n" + " A=arithmetic solving, T=transformational solving.\n\n" "Fuzzing behavior settings:\n" " -Z - sequential queue selection instead of weighted " "random\n" @@ -139,8 +139,8 @@ static void usage(u8 *argv0, int more_help) { "Testing settings:\n" " -s seed - use a fixed seed for the RNG\n" - " -V seconds - fuzz for a specific time then terminate\n" - " -E execs - fuzz for a approx. no of total executions then " + " -V seconds - fuzz for a specified time then terminate\n" + " -E execs - fuzz for an approx. no. of total executions then " "terminate\n" " Note: not precise and can have several more " "executions.\n\n" -- cgit v1.2.3 From 047f3436e95b40d541bcc5b688be0052ef5e798e Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Wed, 24 Feb 2021 21:29:00 +0100 Subject: edges in plot file --- src/afl-fuzz-init.c | 2 +- src/afl-fuzz-stats.c | 21 +++++++++++---------- src/afl-fuzz.c | 8 ++++---- 3 files changed, 16 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index e372c803..ab743f4b 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2026,7 +2026,7 @@ void setup_dirs_fds(afl_state_t *afl) { fprintf(afl->fsrv.plot_file, "# unix_time, cycles_done, cur_path, paths_total, " "pending_total, pending_favs, map_size, unique_crashes, " - "unique_hangs, max_depth, execs_per_sec\n"); + "unique_hangs, max_depth, execs_per_sec, edges_found\n"); fflush(afl->fsrv.plot_file); /* ignore errors */ diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 66efeb20..192fdd62 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -185,15 +185,14 @@ void load_stats_file(afl_state_t *afl) { /* Update stats file for unattended monitoring. */ -void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, - double eps) { +void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, + double stability, double eps) { #ifndef __HAIKU__ struct rusage rus; #endif u64 cur_time = get_cur_time(); - u32 t_bytes = count_non_255_bytes(afl, afl->virgin_bits); u8 fn[PATH_MAX]; FILE *f; @@ -353,7 +352,8 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, /* Update the plot file if there is a reason to. */ -void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) { +void maybe_update_plot_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, + double eps) { if (unlikely(afl->plot_prev_qp == afl->queued_paths && afl->plot_prev_pf == afl->pending_favored && @@ -384,16 +384,16 @@ void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) { /* Fields in the file: unix_time, afl->cycles_done, cur_path, paths_total, paths_not_fuzzed, - favored_not_fuzzed, afl->unique_crashes, afl->unique_hangs, afl->max_depth, - execs_per_sec */ + favored_not_fuzzed, unique_crashes, unique_hangs, max_depth, + execs_per_sec, edges_found */ fprintf( afl->fsrv.plot_file, - "%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f, %llu\n", + "%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f, %llu, %u\n", get_cur_time() / 1000, afl->queue_cycle - 1, afl->current_entry, afl->queued_paths, afl->pending_not_fuzzed, afl->pending_favored, bitmap_cvg, afl->unique_crashes, afl->unique_hangs, afl->max_depth, eps, - afl->plot_prev_ed); /* ignore errors */ + afl->plot_prev_ed, t_bytes); /* ignore errors */ fflush(afl->fsrv.plot_file); @@ -532,7 +532,8 @@ void show_stats(afl_state_t *afl) { if (cur_ms - afl->stats_last_stats_ms > STATS_UPDATE_SEC * 1000) { afl->stats_last_stats_ms = cur_ms; - write_stats_file(afl, t_byte_ratio, stab_ratio, afl->stats_avg_exec); + write_stats_file(afl, t_bytes, t_byte_ratio, stab_ratio, + afl->stats_avg_exec); save_auto(afl); write_bitmap(afl); @@ -555,7 +556,7 @@ void show_stats(afl_state_t *afl) { if (cur_ms - afl->stats_last_plot_ms > PLOT_UPDATE_SEC * 1000) { afl->stats_last_plot_ms = cur_ms; - maybe_update_plot_file(afl, t_byte_ratio, afl->stats_avg_exec); + maybe_update_plot_file(afl, t_bytes, t_byte_ratio, afl->stats_avg_exec); } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index f83aac9e..f029ef83 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1724,8 +1724,8 @@ int main(int argc, char **argv_orig, char **envp) { afl->start_time = get_cur_time(); if (afl->in_place_resume || afl->afl_env.afl_autoresume) load_stats_file(afl); - write_stats_file(afl, 0, 0, 0); - maybe_update_plot_file(afl, 0, 0); + write_stats_file(afl, 0, 0, 0, 0); + maybe_update_plot_file(afl, 0, 0, 0); save_auto(afl); if (afl->stop_soon) { goto stop_fuzzing; } @@ -2018,12 +2018,12 @@ int main(int argc, char **argv_orig, char **envp) { } write_bitmap(afl); - maybe_update_plot_file(afl, 0, 0); + maybe_update_plot_file(afl, 0, 0, 0); save_auto(afl); stop_fuzzing: - write_stats_file(afl, 0, 0, 0); + write_stats_file(afl, 0, 0, 0, 0); afl->force_ui_update = 1; // ensure the screen is reprinted show_stats(afl); // print the screen one last time -- cgit v1.2.3 From 2f7e57f6aa4f09d0b6f55b6592fbd70d2c2c1064 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 25 Feb 2021 10:04:41 +0100 Subject: helper_min3 func --- src/afl-common.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 1628e517..078ffb9d 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -518,8 +518,12 @@ int parse_afl_kill_signal_env(u8 *afl_kill_signal_env, int default_signal) { } -#define HELPER_MIN3(a, b, c) \ - ((a) < (b) ? ((a) < (c) ? (a) : (c)) : ((b) < (c) ? (b) : (c))) +static inline unsigned int helper_min3(unsigned int a, unsigned int b, + unsigned int c) { + + return a < b ? (a < c ? a : c) : (b < c ? b : c); + +} // from // https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#C @@ -539,7 +543,7 @@ static int string_distance_levenshtein(char *s1, char *s2) { for (y = 1, lastdiag = x - 1; y <= s1len; y++) { olddiag = column[y]; - column[y] = HELPER_MIN3(column[y] + 1, column[y - 1] + 1, + column[y] = helper_min3(column[y] + 1, column[y - 1] + 1, lastdiag + (s1[y - 1] == s2[x - 1] ? 0 : 1)); lastdiag = olddiag; @@ -551,8 +555,6 @@ static int string_distance_levenshtein(char *s1, char *s2) { } -#undef HELPER_MIN3 - #define ENV_SIMILARITY_TRESHOLD 3 void print_suggested_envs(char *mispelled_env) { -- cgit v1.2.3 From 6c9777de13ebd9a8c1cd20c2124aff7e4e31d579 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 25 Feb 2021 10:42:39 +0100 Subject: edges in afl-plot --- src/afl-fuzz-init.c | 2 +- src/afl-fuzz-stats.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index ab743f4b..d85a83e0 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2026,7 +2026,7 @@ void setup_dirs_fds(afl_state_t *afl) { fprintf(afl->fsrv.plot_file, "# unix_time, cycles_done, cur_path, paths_total, " "pending_total, pending_favs, map_size, unique_crashes, " - "unique_hangs, max_depth, execs_per_sec, edges_found\n"); + "unique_hangs, max_depth, execs_per_sec, total_execs, edges_found\n"); fflush(afl->fsrv.plot_file); /* ignore errors */ diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 192fdd62..42c71b05 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -355,7 +355,8 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, void maybe_update_plot_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, double eps) { - if (unlikely(afl->plot_prev_qp == afl->queued_paths && + if (unlikely(afl->stop_soon) || + unlikely(afl->plot_prev_qp == afl->queued_paths && afl->plot_prev_pf == afl->pending_favored && afl->plot_prev_pnf == afl->pending_not_fuzzed && afl->plot_prev_ce == afl->current_entry && -- cgit v1.2.3 From ee0ca07f3c9f7c5971440f5dca70a2ee6f37584d Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 25 Feb 2021 12:19:46 +0100 Subject: changing the -t ...+ meaning to "auto-calculate buth this is the max" --- src/afl-fuzz-init.c | 33 ++++++++++++--------------------- src/afl-fuzz-stats.c | 16 ++++++++-------- src/afl-fuzz.c | 33 +++++++++++++++++++++++++++++---- 3 files changed, 49 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index d85a83e0..3dbc4c65 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -882,32 +882,23 @@ void perform_dry_run(afl_state_t *afl) { if (afl->timeout_given) { - /* The -t nn+ syntax in the command line sets afl->timeout_given to - '2' and instructs afl-fuzz to tolerate but skip queue entries that - time out. */ + /* if we have a timeout but a timeout value was given then always + skip. The '+' meaning has been changed! */ + WARNF("Test case results in a timeout (skipping)"); + ++cal_failures; + q->cal_failed = CAL_CHANCES; + q->disabled = 1; + q->perf_score = 0; - if (afl->timeout_given > 1) { + if (!q->was_fuzzed) { - WARNF("Test case results in a timeout (skipping)"); - q->cal_failed = CAL_CHANCES; - ++cal_failures; - break; + q->was_fuzzed = 1; + --afl->pending_not_fuzzed; + --afl->active_paths; } - SAYF("\n" cLRD "[-] " cRST - "The program took more than %u ms to process one of the initial " - "test cases.\n" - " Usually, the right thing to do is to relax the -t option - " - "or to delete it\n" - " altogether and allow the fuzzer to auto-calibrate. That " - "said, if you know\n" - " what you are doing and want to simply skip the unruly test " - "cases, append\n" - " '+' at the end of the value passed to -t ('-t %u+').\n", - afl->fsrv.exec_tmout, afl->fsrv.exec_tmout); - - FATAL("Test case '%s' results in a timeout", fn); + break; } else { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 42c71b05..bd856088 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -388,13 +388,13 @@ void maybe_update_plot_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, favored_not_fuzzed, unique_crashes, unique_hangs, max_depth, execs_per_sec, edges_found */ - fprintf( - afl->fsrv.plot_file, - "%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f, %llu, %u\n", - get_cur_time() / 1000, afl->queue_cycle - 1, afl->current_entry, - afl->queued_paths, afl->pending_not_fuzzed, afl->pending_favored, - bitmap_cvg, afl->unique_crashes, afl->unique_hangs, afl->max_depth, eps, - afl->plot_prev_ed, t_bytes); /* ignore errors */ + fprintf(afl->fsrv.plot_file, + "%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f, %llu, " + "%u\n", + get_cur_time() / 1000, afl->queue_cycle - 1, afl->current_entry, + afl->queued_paths, afl->pending_not_fuzzed, afl->pending_favored, + bitmap_cvg, afl->unique_crashes, afl->unique_hangs, afl->max_depth, + eps, afl->plot_prev_ed, t_bytes); /* ignore errors */ fflush(afl->fsrv.plot_file); @@ -1219,7 +1219,7 @@ void show_init_stats(afl_state_t *afl) { stringify_int(IB(0), min_us), stringify_int(IB(1), max_us), stringify_int(IB(2), avg_us)); - if (!afl->timeout_given) { + if (afl->timeout_given != 1) { /* Figure out the appropriate timeout. The basic idea is: 5x average or 1x max, rounded up to EXEC_TM_ROUND ms and capped at 1 second. diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 5810e9a9..a02eadb2 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -103,9 +103,10 @@ static void usage(u8 *argv0, int more_help) { " quad -- see docs/power_schedules.md\n" " -f file - location read by the fuzzed program (default: stdin " "or @@)\n" - " -t msec - timeout for each run (auto-scaled, 50-... ms, default " - "%u ms)\n" - " add a '+' to skip over seeds running longer.\n" + " -t msec - timeout for each run (auto-scaled, default %u ms). " + "Add a '+'\n" + " to auto-calculate the timeout, the value being the " + "maximum.\n" " -m megs - memory limit for child process (%u MB, 0 = no limit " "[default])\n" " -Q - use binary-only instrumentation (QEMU mode)\n" @@ -1453,7 +1454,7 @@ int main(int argc, char **argv_orig, char **envp) { } - if (!afl->timeout_given) { find_timeout(afl); } + if (!afl->timeout_given) { find_timeout(afl); } // only for resumes! if ((afl->tmp_dir = afl->afl_env.afl_tmpdir) != NULL && !afl->in_place_resume) { @@ -1718,6 +1719,30 @@ int main(int argc, char **argv_orig, char **envp) { } + if (afl->timeout_given == 2) { // -t ...+ option + + if (valid_seeds == 1) { + + WARNF( + "Only one valid seed is present, auto-calculating the timeout is " + "disabled!"); + afl->timeout_given = 1; + + } else { + + u64 max_ms = 0; + + for (entry = 0; entry < afl->queued_paths; ++entry) + if (!afl->queue_buf[entry]->disabled) + if (afl->queue_buf[entry]->exec_us > max_ms) + max_ms = afl->queue_buf[entry]->exec_us; + + afl->fsrv.exec_tmout = max_ms; + + } + + } + show_init_stats(afl); if (unlikely(afl->old_seed_selection)) seek_to = find_start_position(afl); -- cgit v1.2.3 From 79f1a44a01775ab28ad39f21f09e084fcd773c98 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 27 Feb 2021 18:14:50 +0100 Subject: fix qasan search path --- src/afl-common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 078ffb9d..c341bb97 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -372,11 +372,11 @@ u8 *get_libqasan_path(u8 *own_loc) { } - if (!access(BIN_PATH "/libqasan.so", X_OK)) { + if (!access(AFL_PATH "/libqasan.so", X_OK)) { if (cp) { ck_free(cp); } - return ck_strdup(BIN_PATH "/libqasan.so"); + return ck_strdup(AFL_PATH "/libqasan.so"); } -- cgit v1.2.3 From f81ef4abf41184a24d24828841c82b98b9216ddc Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 28 Feb 2021 00:12:21 +0100 Subject: fix afl-common compile --- src/afl-common.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index c341bb97..fa4aec7f 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -47,6 +47,10 @@ u8 be_quiet = 0; u8 *doc_path = ""; u8 last_intr = 0; +#ifndef AFL_PATH + #define AFL_PATH "/usr/local/lib/afl/" +#endif + void detect_file_args(char **argv, u8 *prog_in, bool *use_stdin) { u32 i = 0; -- cgit v1.2.3 From 4619a1395b9a414e5e11148d79fde3a7fa348e87 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 1 Mar 2021 09:57:57 +0100 Subject: ensure proper aligning for skim patch --- src/afl-common.c | 2 +- src/afl-forkserver.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index fa4aec7f..a306fe5e 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -1135,7 +1135,7 @@ u32 get_map_size(void) { } - if (map_size % 32) { map_size = (((map_size >> 5) + 1) << 5); } + if (map_size % 64) { map_size = (((map_size >> 6) + 1) << 6); } } diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 9ee59822..fd5edc98 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -656,11 +656,11 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (!fsrv->map_size) { fsrv->map_size = MAP_SIZE; } - if (unlikely(tmp_map_size % 32)) { + if (unlikely(tmp_map_size % 64)) { // should not happen WARNF("Target reported non-aligned map size of %u", tmp_map_size); - tmp_map_size = (((tmp_map_size + 31) >> 5) << 5); + tmp_map_size = (((tmp_map_size + 63) >> 6) << 6); } -- cgit v1.2.3 From 7259075b71924e7ab68546aca04fa5ecfe2d93d6 Mon Sep 17 00:00:00 2001 From: aflpp Date: Mon, 1 Mar 2021 19:13:29 +0100 Subject: len for cmplog rtn --- src/afl-fuzz-redqueen.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 1ab5f996..9bfbf95b 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -1853,7 +1853,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, - u8 *o_pattern, u8 *changed_val, u32 idx, + u8 *o_pattern, u8 *changed_val, u8 plen, u32 idx, u32 taint_len, u8 *orig_buf, u8 *buf, u8 *cbuf, u32 len, u8 lvl, u8 *status) { @@ -1866,7 +1866,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl, u8 save[40]; u32 saved_idx = idx, pre, from = 0, to = 0, i, j; - u32 its_len = MIN((u32)32, len - idx); + u32 its_len = MIN((u32)plen, len - idx); its_len = MIN(its_len, taint_len); u32 saved_its_len = its_len; @@ -2365,9 +2365,9 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, status = 0; - if (unlikely(rtn_extend_encoding(afl, o->v0, o->v1, orig_o->v0, - orig_o->v1, idx, taint_len, orig_buf, - buf, cbuf, len, lvl, &status))) { + if (unlikely(rtn_extend_encoding( + afl, o->v0, o->v1, orig_o->v0, orig_o->v1, SHAPE_BYTES(h->shape), + idx, taint_len, orig_buf, buf, cbuf, len, lvl, &status))) { return 1; @@ -2382,9 +2382,9 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, status = 0; - if (unlikely(rtn_extend_encoding(afl, o->v1, o->v0, orig_o->v1, - orig_o->v0, idx, taint_len, orig_buf, - buf, cbuf, len, lvl, &status))) { + if (unlikely(rtn_extend_encoding( + afl, o->v1, o->v0, orig_o->v1, orig_o->v0, SHAPE_BYTES(h->shape), + idx, taint_len, orig_buf, buf, cbuf, len, lvl, &status))) { return 1; -- cgit v1.2.3 From 108e588e888df5c2679600ea49846a565bac23f9 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 2 Mar 2021 17:46:43 +0100 Subject: add de-unicoded dictionary entries --- src/afl-fuzz-extras.c | 149 ++++++++++++++++++++++++++++++++++++++++++-------- src/afl-fuzz.c | 7 ++- 2 files changed, 131 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 7ecad233..52100fa1 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -387,6 +387,130 @@ static inline u8 memcmp_nocase(u8 *m1, u8 *m2, u32 len) { } +/* add an extra/dict/token - no checks performed, no sorting */ + +static void add_extra_nocheck(afl_state_t *afl, u8 *mem, u32 len) { + + afl->extras = afl_realloc((void **)&afl->extras, + (afl->extras_cnt + 1) * sizeof(struct extra_data)); + + if (unlikely(!afl->extras)) { PFATAL("alloc"); } + + afl->extras[afl->extras_cnt].data = ck_alloc(len); + afl->extras[afl->extras_cnt].len = len; + memcpy(afl->extras[afl->extras_cnt].data, mem, len); + afl->extras_cnt++; + + /* We only want to print this once */ + + if (afl->extras_cnt == afl->max_det_extras + 1) { + + WARNF("More than %u tokens - will use them probabilistically.", + afl->max_det_extras); + + } + +} + +/* Sometimes strings in input is transformed to unicode internally, so for + fuzzing we should attempt to de-unicode if it looks like simple unicode */ + +void deunicode_extras(afl_state_t *afl) { + + if (!afl->extras_cnt) return; + + u32 i, j, orig_cnt = afl->extras_cnt; + u8 buf[64]; + + for (i = 0; i < orig_cnt; ++i) { + + if (afl->extras[i].len < 6 || afl->extras[i].len > 64 || + afl->extras[i].len % 2) { + + continue; + + } + + u32 k = 0, z1 = 0, z2 = 0, z3 = 0, z4 = 0, half = afl->extras[i].len >> 1; + u32 quarter = half >> 1; + + for (j = 0; j < afl->extras[i].len; ++j) { + + switch (j % 4) { + + case 2: + if (!afl->extras[i].data[j]) { ++z3; } + // fall through + case 0: + if (!afl->extras[i].data[j]) { ++z1; } + break; + case 3: + if (!afl->extras[i].data[j]) { ++z4; } + // fall through + case 1: + if (!afl->extras[i].data[j]) { ++z2; } + break; + + } + + } + + if ((z1 < half && z2 < half) || z1 + z2 == afl->extras[i].len) { continue; } + + // also maybe 32 bit unicode? + if (afl->extras[i].len % 4 == 0 && afl->extras[i].len >= 12 && + (z3 == quarter || z4 == quarter) && z1 + z2 == quarter * 3) { + + for (j = 0; j < afl->extras[i].len; ++j) { + + if (z4 < quarter) { + + if (j % 4 == 3) { buf[k++] = afl->extras[i].data[j]; } + + } else if (z3 < quarter) { + + if (j % 4 == 2) { buf[k++] = afl->extras[i].data[j]; } + + } else if (z2 < half) { + + if (j % 4 == 1) { buf[k++] = afl->extras[i].data[j]; } + + } else { + + if (j % 4 == 0) { buf[k++] = afl->extras[i].data[j]; } + + } + + } + + add_extra_nocheck(afl, buf, k); + k = 0; + + } + + for (j = 0; j < afl->extras[i].len; ++j) { + + if (z1 < half) { + + if (j % 2 == 0) { buf[k++] = afl->extras[i].data[j]; } + + } else { + + if (j % 2 == 1) { buf[k++] = afl->extras[i].data[j]; } + + } + + } + + add_extra_nocheck(afl, buf, k); + + } + + qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data), + compare_extras_len); + +} + /* Removes duplicates from the loaded extras. This can happen if multiple files are loaded */ @@ -396,9 +520,9 @@ void dedup_extras(afl_state_t *afl) { u32 i, j, orig_cnt = afl->extras_cnt; - for (i = 0; i < afl->extras_cnt - 1; i++) { + for (i = 0; i < afl->extras_cnt - 1; ++i) { - for (j = i + 1; j < afl->extras_cnt; j++) { + for (j = i + 1; j < afl->extras_cnt; ++j) { restart_dedup: @@ -462,30 +586,11 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) { } - afl->extras = afl_realloc((void **)&afl->extras, - (afl->extras_cnt + 1) * sizeof(struct extra_data)); - - if (unlikely(!afl->extras)) { PFATAL("alloc"); } - - afl->extras[afl->extras_cnt].data = ck_alloc(len); - afl->extras[afl->extras_cnt].len = len; - - memcpy(afl->extras[afl->extras_cnt].data, mem, len); - - afl->extras_cnt++; + add_extra_nocheck(afl, mem, len); qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data), compare_extras_len); - /* We only want to print this once */ - - if (afl->extras_cnt == afl->max_det_extras + 1) { - - WARNF("More than %u tokens - will use them probabilistically.", - afl->max_det_extras); - - } - } /* Maybe add automatic extra. */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index a02eadb2..90f77919 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1449,9 +1449,6 @@ int main(int argc, char **argv_orig, char **envp) { } - dedup_extras(afl); - OKF("Loaded a total of %u extras.", afl->extras_cnt); - } if (!afl->timeout_given) { find_timeout(afl); } // only for resumes! @@ -1681,6 +1678,10 @@ int main(int argc, char **argv_orig, char **envp) { } + deunicode_extras(afl); + dedup_extras(afl); + if (afl->extras_cnt) { OKF("Loaded a total of %u extras.", afl->extras_cnt); } + // after we have the correct bitmap size we can read the bitmap -B option // and set the virgin maps if (afl->in_bitmap) { -- cgit v1.2.3 From f0c7967fbf4d6d3906693896f511b6679573c02b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 3 Mar 2021 08:58:09 +0100 Subject: add new tutorial --- src/afl-fuzz.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 90f77919..09aff4fb 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1437,20 +1437,8 @@ int main(int argc, char **argv_orig, char **envp) { // read_foreign_testcases(afl, 1); for the moment dont do this OKF("Loaded a total of %u seeds.", afl->queued_paths); - load_auto(afl); - pivot_inputs(afl); - if (extras_dir_cnt) { - - for (i = 0; i < extras_dir_cnt; i++) { - - load_extras(afl, extras_dir[i]); - - } - - } - if (!afl->timeout_given) { find_timeout(afl); } // only for resumes! if ((afl->tmp_dir = afl->afl_env.afl_tmpdir) != NULL && @@ -1678,6 +1666,18 @@ int main(int argc, char **argv_orig, char **envp) { } + load_auto(afl); + + if (extras_dir_cnt) { + + for (i = 0; i < extras_dir_cnt; i++) { + + load_extras(afl, extras_dir[i]); + + } + + } + deunicode_extras(afl); dedup_extras(afl); if (afl->extras_cnt) { OKF("Loaded a total of %u extras.", afl->extras_cnt); } -- cgit v1.2.3 From 1e76079e93f5b4a9729367dd982d632013669bc5 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 4 Mar 2021 11:32:32 +0100 Subject: llvm mode CALLER mode --- src/afl-cc.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index c3910e6d..9cf02059 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -73,7 +73,8 @@ enum { INSTRUMENT_GCC = 6, INSTRUMENT_CLANG = 7, INSTRUMENT_OPT_CTX = 8, - INSTRUMENT_OPT_NGRAM = 16 + INSTRUMENT_OPT_NGRAM = 16, + INSTRUMENT_OPT_CALLER = 32, }; @@ -1273,7 +1274,8 @@ int main(int argc, char **argv, char **envp) { } if (getenv("AFL_LLVM_CTX")) instrument_opt_mode |= INSTRUMENT_OPT_CTX; - + if (getenv("AFL_LLVM_CALLER")) instrument_opt_mode |= INSTRUMENT_OPT_CALLER; + if (getenv("AFL_LLVM_NGRAM_SIZE")) { instrument_opt_mode |= INSTRUMENT_OPT_NGRAM; @@ -1387,6 +1389,13 @@ int main(int argc, char **argv, char **envp) { setenv("AFL_LLVM_CTX", "1", 1); } + + if (strncasecmp(ptr2, "caller", strlen("caller")) == 0) { + + instrument_opt_mode |= INSTRUMENT_OPT_CALLER; + setenv("AFL_LLVM_CALLER", "1", 1); + + } if (strncasecmp(ptr2, "ngram", strlen("ngram")) == 0) { @@ -1420,6 +1429,11 @@ int main(int argc, char **argv, char **envp) { } } + + if ((instrument_opt_mode & INSTRUMENT_OPT_CTX) && + (instrument_opt_mode & INSTRUMENT_OPT_CALLER)) { + FATAL("you cannot set CTX and CALLER together"); + } if (instrument_opt_mode && instrument_mode == INSTRUMENT_DEFAULT && (compiler_mode == LLVM || compiler_mode == UNSET)) { @@ -1770,7 +1784,7 @@ int main(int argc, char **argv, char **envp) { } if (instrument_opt_mode && compiler_mode != LLVM) - FATAL("CTX and NGRAM can only be used in LLVM mode"); + FATAL("CTX, CALLER and NGRAM can only be used in LLVM mode"); if (!instrument_opt_mode) { @@ -1780,15 +1794,14 @@ int main(int argc, char **argv, char **envp) { } else { - if (instrument_opt_mode == INSTRUMENT_OPT_CTX) - - ptr = alloc_printf("%s + CTX", instrument_mode_string[instrument_mode]); - else if (instrument_opt_mode == INSTRUMENT_OPT_NGRAM) - ptr = alloc_printf("%s + NGRAM-%u", - instrument_mode_string[instrument_mode], ngram_size); - else - ptr = alloc_printf("%s + CTX + NGRAM-%u", - instrument_mode_string[instrument_mode], ngram_size); + char *ptr2 = alloc_printf(" + NGRAM-%u", ngram_size); + ptr = alloc_printf("%s%s%s%s", instrument_mode_string[instrument_mode], + (instrument_opt_mode & INSTRUMENT_OPT_CTX) ? " + CTX" : "", + (instrument_opt_mode & INSTRUMENT_OPT_CALLER) ? " + CALLER" : "", + (instrument_opt_mode & INSTRUMENT_OPT_NGRAM) ? ptr2 : "" + ); + + ck_free(ptr2); } -- cgit v1.2.3 From 8f538e77ed75256466e8b97d43d0c32948cb9931 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 4 Mar 2021 11:33:51 +0100 Subject: code format --- src/afl-cc.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 9cf02059..0c689286 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1275,7 +1275,7 @@ int main(int argc, char **argv, char **envp) { if (getenv("AFL_LLVM_CTX")) instrument_opt_mode |= INSTRUMENT_OPT_CTX; if (getenv("AFL_LLVM_CALLER")) instrument_opt_mode |= INSTRUMENT_OPT_CALLER; - + if (getenv("AFL_LLVM_NGRAM_SIZE")) { instrument_opt_mode |= INSTRUMENT_OPT_NGRAM; @@ -1389,7 +1389,7 @@ int main(int argc, char **argv, char **envp) { setenv("AFL_LLVM_CTX", "1", 1); } - + if (strncasecmp(ptr2, "caller", strlen("caller")) == 0) { instrument_opt_mode |= INSTRUMENT_OPT_CALLER; @@ -1429,10 +1429,12 @@ int main(int argc, char **argv, char **envp) { } } - + if ((instrument_opt_mode & INSTRUMENT_OPT_CTX) && (instrument_opt_mode & INSTRUMENT_OPT_CALLER)) { + FATAL("you cannot set CTX and CALLER together"); + } if (instrument_opt_mode && instrument_mode == INSTRUMENT_DEFAULT && @@ -1795,12 +1797,12 @@ int main(int argc, char **argv, char **envp) { } else { char *ptr2 = alloc_printf(" + NGRAM-%u", ngram_size); - ptr = alloc_printf("%s%s%s%s", instrument_mode_string[instrument_mode], + ptr = alloc_printf( + "%s%s%s%s", instrument_mode_string[instrument_mode], (instrument_opt_mode & INSTRUMENT_OPT_CTX) ? " + CTX" : "", (instrument_opt_mode & INSTRUMENT_OPT_CALLER) ? " + CALLER" : "", - (instrument_opt_mode & INSTRUMENT_OPT_NGRAM) ? ptr2 : "" - ); - + (instrument_opt_mode & INSTRUMENT_OPT_NGRAM) ? ptr2 : ""); + ck_free(ptr2); } -- cgit v1.2.3 From 96c526cb78512737a980726dd32c95593edb8cd1 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 4 Mar 2021 14:04:40 +0100 Subject: fix caller/ctx change, support dlopen in afl-compiler-rt --- src/afl-cc.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 0c689286..ab794877 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -89,7 +89,7 @@ char instrument_mode_string[18][18] = { "GCC", "CLANG", "CTX", - "", + "CALLER", "", "", "", @@ -1514,12 +1514,13 @@ int main(int argc, char **argv, char **envp) { " CLASSIC %s no yes module yes yes " "yes\n" " - NORMAL\n" + " - CALLER\n" " - CTX\n" " - NGRAM-{2-16}\n" " INSTRIM no yes module yes yes " " yes\n" " - NORMAL\n" - " - CTX\n" + " - CALLER\n" " - NGRAM-{2-16}\n" " [GCC_PLUGIN] gcc plugin: %s%s\n" " CLASSIC DEFAULT no yes no no no " @@ -1566,7 +1567,10 @@ int main(int argc, char **argv, char **envp) { NATIVE_MSG " CLASSIC: decision target instrumentation (README.llvm.md)\n" - " CTX: CLASSIC + callee context (instrumentation/README.ctx.md)\n" + " CALLER: CLASSIC + single callee context " + "(instrumentation/README.ctx.md)\n" + " CTX: CLASSIC + full callee context " + "(instrumentation/README.ctx.md)\n" " NGRAM-x: CLASSIC + previous path " "((instrumentation/README.ngram.md)\n" " INSTRIM: Dominator tree (for LLVM <= 6.0) " @@ -1660,15 +1664,17 @@ int main(int argc, char **argv, char **envp) { " AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen " "mutator)\n" " AFL_LLVM_INSTRUMENT: set instrumentation mode:\n" - " CLASSIC, INSTRIM, PCGUARD, LTO, GCC, CLANG, CTX, NGRAM-2 ... " - "NGRAM-16\n" + " CLASSIC, INSTRIM, PCGUARD, LTO, GCC, CLANG, CALLER, CTX, " + "NGRAM-2 ..-16\n" " You can also use the old environment variables instead:\n" " AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n" " AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n" " AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed " "(option to INSTRIM)\n" - " AFL_LLVM_CTX: use context sensitive coverage (for CLASSIC and " - "INSTRIM)\n" + " AFL_LLVM_CALLER: use single context sensitive coverage (for " + "CLASSIC)\n" + " AFL_LLVM_CTX: use full context sensitive coverage (for " + "CLASSIC)\n" " AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage (for " "CLASSIC & INSTRIM)\n"); @@ -1814,11 +1820,14 @@ int main(int argc, char **argv, char **envp) { "(requires LLVM 11 or higher)"); #endif - if (instrument_opt_mode && instrument_mode != INSTRUMENT_CLASSIC && - instrument_mode != INSTRUMENT_CFG) + if (instrument_opt_mode && instrument_mode == INSTRUMENT_CFG && + instrument_opt_mode & INSTRUMENT_OPT_CTX) + FATAL("CFG instrumentation mode supports NGRAM and CALLER, but not CTX."); + else if (instrument_opt_mode && instrument_mode != INSTRUMENT_CLASSIC) + // we will drop CFG/INSTRIM in the future so do not advertise FATAL( - "CTX and NGRAM instrumentation options can only be used with LLVM and " - "CFG or CLASSIC instrumentation modes!"); + "CALLER, CTX and NGRAM instrumentation options can only be used with " + "the LLVM CLASSIC instrumentation mode."); if (getenv("AFL_LLVM_SKIP_NEVERZERO") && getenv("AFL_LLVM_NOT_ZERO")) FATAL( -- cgit v1.2.3 From 0aa93afeb82c610fd39b5dd4a3dd7482b9f86b1e Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 4 Mar 2021 14:50:26 +0100 Subject: vectorial top-k CTX first implementation --- src/afl-cc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 0c689286..3c96beac 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -22,7 +22,7 @@ #include "types.h" #include "debug.h" #include "alloc-inl.h" -#include "llvm-ngram-coverage.h" +#include "llvm-alternative-coverage.h" #include #include -- cgit v1.2.3 From b6dc529bc38469a69ca5f43e12e9cb921fdc3a08 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 4 Mar 2021 14:55:57 +0100 Subject: no ASAN odr violations by default --- src/afl-analyze.c | 1 + src/afl-forkserver.c | 1 + src/afl-showmap.c | 1 + src/afl-tmin.c | 1 + 4 files changed, 4 insertions(+) (limited to 'src') diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 20aef2da..d46ecb8d 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -785,6 +785,7 @@ static void set_up_environment(void) { "abort_on_error=1:" "detect_leaks=0:" "allocator_may_return_null=1:" + "detect_odr_violation=0:" "symbolize=0:" "handle_segv=0:" "handle_sigbus=0:" diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index fd5edc98..a129c152 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -492,6 +492,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "malloc_context_size=0:" "symbolize=0:" "allocator_may_return_null=1:" + "detect_odr_violation=0:" "handle_segv=0:" "handle_sigbus=0:" "handle_abort=0:" diff --git a/src/afl-showmap.c b/src/afl-showmap.c index b40527d3..0fc76193 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -563,6 +563,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) { "detect_leaks=0:" "allocator_may_return_null=1:" "symbolize=0:" + "detect_odr_violation=0:" "handle_segv=0:" "handle_sigbus=0:" "handle_abort=0:" diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 15336959..6d04c652 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -717,6 +717,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) { "detect_leaks=0:" "allocator_may_return_null=1:" "symbolize=0:" + "detect_odr_violation=0:" "handle_segv=0:" "handle_sigbus=0:" "handle_abort=0:" -- cgit v1.2.3 From af9aeb89d43919fb5e538778e5df9bf3ffaba0aa Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Thu, 4 Mar 2021 15:26:15 +0100 Subject: afl-cc code for k-ctx --- src/afl-cc.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 3c96beac..97f32b2b 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -50,7 +50,7 @@ static u8 **cc_params; /* Parameters passed to the real CC */ 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, lto_mode; +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 have_gcc, have_llvm, have_gcc_plugin, have_lto, have_instr_list = 0; static u8 * lto_flag = AFL_CLANG_FLTO, *argvnull; @@ -75,6 +75,7 @@ enum { INSTRUMENT_OPT_CTX = 8, INSTRUMENT_OPT_NGRAM = 16, INSTRUMENT_OPT_CALLER = 32, + INSTRUMENT_OPT_CTX_K = 64, }; @@ -1282,11 +1283,21 @@ int main(int argc, char **argv, char **envp) { ngram_size = atoi(getenv("AFL_LLVM_NGRAM_SIZE")); if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX) FATAL( - "NGRAM instrumentation mode must be between 2 and NGRAM_SIZE_MAX " + "K-CTX instrumentation mode must be between 2 and NGRAM_SIZE_MAX " "(%u)", NGRAM_SIZE_MAX); } + + if (getenv("AFL_LLVM_CTX_K")) { + + instrument_opt_mode |= INSTRUMENT_OPT_CTX_K; + ctx_k = atoi(getenv("AFL_LLVM_CTX_K")); + if (ctx_k < 1 || ctx_k > CTX_MAX_K) + FATAL( + "NGRAM instrumentation mode must be between 1 and CTX_MAX_K (%u)", CTX_MAX_K); + + } if (getenv("AFL_LLVM_INSTRUMENT")) { @@ -1382,6 +1393,32 @@ int main(int argc, char **argv, char **envp) { compiler_mode = CLANG; } + + if (strncasecmp(ptr2, "ctx-", strlen("ctx-")) == 0) { + + u8 *ptr3 = ptr2 + strlen("ctx-"); + while (*ptr3 && (*ptr3 < '0' || *ptr3 > '9')) + ptr3++; + + if (!*ptr3) { + + if ((ptr3 = getenv("AFL_LLVM_CTX_K")) == NULL) + FATAL( + "you must set the K-CTX K with (e.g. for value 2) " + "AFL_LLVM_INSTRUMENT=ctx-2"); + + } + + ctx_k = atoi(ptr3); + if (ctx_k < 1 || ctx_k > CTX_MAX_K) + FATAL( + "K-CTX instrumentation option must be between 1 and CTX_MAX_K (%u)", + CTX_MAX_K); + instrument_opt_mode |= (INSTRUMENT_OPT_CTX_K); + u8 *ptr4 = alloc_printf("%u", ctx_k); + setenv("AFL_LLVM_CTX_K", ptr4, 1); + + } if (strncasecmp(ptr2, "ctx", strlen("ctx")) == 0) { @@ -1437,6 +1474,20 @@ int main(int argc, char **argv, char **envp) { } + if ((instrument_opt_mode & INSTRUMENT_OPT_CTX) && + (instrument_opt_mode & INSTRUMENT_OPT_CTX_K)) { + + FATAL("you cannot set CTX and K-CTX together"); + + } + + if ((instrument_opt_mode & INSTRUMENT_OPT_CALLER) && + (instrument_opt_mode & INSTRUMENT_OPT_CTX_K)) { + + FATAL("you cannot set CALLER and K-CTX together"); + + } + if (instrument_opt_mode && instrument_mode == INSTRUMENT_DEFAULT && (compiler_mode == LLVM || compiler_mode == UNSET)) { @@ -1797,13 +1848,18 @@ int main(int argc, char **argv, char **envp) { } else { char *ptr2 = alloc_printf(" + NGRAM-%u", ngram_size); + char *ptr3 = alloc_printf(" + K-CTX-%u", ctx_k); + ptr = alloc_printf( - "%s%s%s%s", instrument_mode_string[instrument_mode], + "%s%s%s%s%s", instrument_mode_string[instrument_mode], (instrument_opt_mode & INSTRUMENT_OPT_CTX) ? " + CTX" : "", (instrument_opt_mode & INSTRUMENT_OPT_CALLER) ? " + CALLER" : "", - (instrument_opt_mode & INSTRUMENT_OPT_NGRAM) ? ptr2 : ""); + (instrument_opt_mode & INSTRUMENT_OPT_NGRAM) ? ptr2 : "", + (instrument_opt_mode & INSTRUMENT_OPT_CTX_K) ? ptr3 : "" + ); ck_free(ptr2); + ck_free(ptr3); } -- cgit v1.2.3 From a2f40aa285faa75e78ac1ffffe8d79e2ac1a40da Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 4 Mar 2021 22:10:32 +0100 Subject: disable corpus introspection, potentially creates huge data --- src/afl-fuzz-queue.c | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index ad3e3b8e..835aba40 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -198,34 +198,35 @@ void create_alias_table(afl_state_t *afl) { while (nS) afl->alias_probability[S[--nS]] = 1; -#ifdef INTROSPECTION - u8 fn[PATH_MAX]; - snprintf(fn, PATH_MAX, "%s/introspection_corpus.txt", afl->out_dir); - FILE *f = fopen(fn, "a"); - if (f) { + /* + #ifdef INTROSPECTION + u8 fn[PATH_MAX]; + snprintf(fn, PATH_MAX, "%s/introspection_corpus.txt", afl->out_dir); + FILE *f = fopen(fn, "a"); + if (f) { + + for (i = 0; i < n; i++) { + + struct queue_entry *q = afl->queue_buf[i]; + fprintf( + f, + "entry=%u name=%s favored=%s variable=%s disabled=%s len=%u " + "exec_us=%u " + "bitmap_size=%u bitsmap_size=%u tops=%u weight=%f perf_score=%f\n", + i, q->fname, q->favored ? "true" : "false", + q->var_behavior ? "true" : "false", q->disabled ? "true" : "false", + q->len, (u32)q->exec_us, q->bitmap_size, q->bitsmap_size, q->tc_ref, + q->weight, q->perf_score); - for (i = 0; i < n; i++) { + } - struct queue_entry *q = afl->queue_buf[i]; - fprintf( - f, - "entry=%u name=%s favored=%s variable=%s disabled=%s len=%u " - "exec_us=%u " - "bitmap_size=%u bitsmap_size=%u tops=%u weight=%f perf_score=%f\n", - i, q->fname, q->favored ? "true" : "false", - q->var_behavior ? "true" : "false", q->disabled ? "true" : "false", - q->len, (u32)q->exec_us, q->bitmap_size, q->bitsmap_size, q->tc_ref, - q->weight, q->perf_score); + fprintf(f, "\n"); + fclose(f); } - fprintf(f, "\n"); - fclose(f); - - } - -#endif - + #endif + */ /* fprintf(stderr, " entry alias probability perf_score weight filename\n"); for (u32 i = 0; i < n; ++i) fprintf(stderr, " %5u %5u %11u -- cgit v1.2.3 From f848562732337c2d3c71ace4667b3130574f0fe4 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 5 Mar 2021 10:15:38 +0100 Subject: point explicitly to AFL_MAP_SIZE on problems --- src/afl-forkserver.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index a129c152..6f08f9f4 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -909,10 +909,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } else if (!fsrv->mem_limit) { SAYF("\n" cLRD "[-] " cRST - "Hmm, looks like the target binary terminated before we could" - " complete a handshake with the injected code.\n" - "If the target was compiled with afl-clang-lto and AFL_LLVM_MAP_ADDR" - " then recompiling without this parameter.\n" + "Hmm, looks like the target binary terminated before we could complete" + " a\n" + "handshake with the injected code.\n" + "Most likely the target has a huge coverage map, retry with setting" + " the\n" + "environment variable AFL_MAP_SIZE=4194304\n" "Otherwise there is a horrible bug in the fuzzer.\n" "Poke for troubleshooting tips.\n"); @@ -928,6 +930,10 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "explanations:\n\n" "%s" + + " - Most likely the target has a huge coverage map, retry with setting the\n" + " environment variable AFL_MAP_SIZE=4194304\n\n" + " - The current memory limit (%s) is too restrictive, causing an " "OOM\n" " fault in the dynamic linker. This can be fixed with the -m " -- cgit v1.2.3 From c429021de10cf01878bd2150cc68c6b403db9335 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Fri, 5 Mar 2021 15:27:10 +0100 Subject: fix typos and format --- src/afl-cc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 97f32b2b..e4ea66e4 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1283,19 +1283,19 @@ int main(int argc, char **argv, char **envp) { ngram_size = atoi(getenv("AFL_LLVM_NGRAM_SIZE")); if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX) FATAL( - "K-CTX instrumentation mode must be between 2 and NGRAM_SIZE_MAX " + "NGRAM instrumentation mode must be between 2 and NGRAM_SIZE_MAX " "(%u)", NGRAM_SIZE_MAX); } - + if (getenv("AFL_LLVM_CTX_K")) { instrument_opt_mode |= INSTRUMENT_OPT_CTX_K; ctx_k = atoi(getenv("AFL_LLVM_CTX_K")); if (ctx_k < 1 || ctx_k > CTX_MAX_K) - FATAL( - "NGRAM instrumentation mode must be between 1 and CTX_MAX_K (%u)", CTX_MAX_K); + FATAL("K-CTX instrumentation mode must be between 1 and CTX_MAX_K (%u)", + CTX_MAX_K); } @@ -1393,7 +1393,7 @@ int main(int argc, char **argv, char **envp) { compiler_mode = CLANG; } - + if (strncasecmp(ptr2, "ctx-", strlen("ctx-")) == 0) { u8 *ptr3 = ptr2 + strlen("ctx-"); @@ -1412,7 +1412,8 @@ int main(int argc, char **argv, char **envp) { ctx_k = atoi(ptr3); if (ctx_k < 1 || ctx_k > CTX_MAX_K) FATAL( - "K-CTX instrumentation option must be between 1 and CTX_MAX_K (%u)", + "K-CTX instrumentation option must be between 1 and CTX_MAX_K " + "(%u)", CTX_MAX_K); instrument_opt_mode |= (INSTRUMENT_OPT_CTX_K); u8 *ptr4 = alloc_printf("%u", ctx_k); @@ -1855,8 +1856,7 @@ int main(int argc, char **argv, char **envp) { (instrument_opt_mode & INSTRUMENT_OPT_CTX) ? " + CTX" : "", (instrument_opt_mode & INSTRUMENT_OPT_CALLER) ? " + CALLER" : "", (instrument_opt_mode & INSTRUMENT_OPT_NGRAM) ? ptr2 : "", - (instrument_opt_mode & INSTRUMENT_OPT_CTX_K) ? ptr3 : "" - ); + (instrument_opt_mode & INSTRUMENT_OPT_CTX_K) ? ptr3 : ""); ck_free(ptr2); ck_free(ptr3); -- cgit v1.2.3 From 74a6044b3fba496c1255f9aedbf5b7253ae29f0e Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 9 Mar 2021 14:11:52 +0100 Subject: fix sanitizer settings --- src/afl-forkserver.c | 17 +++++++++-------- src/afl-fuzz-init.c | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 6f08f9f4..82ec3069 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -481,11 +481,11 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, /* This should improve performance a bit, since it stops the linker from doing extra work post-fork(). */ - if (!getenv("LD_BIND_LAZY")) { setenv("LD_BIND_NOW", "1", 0); } + if (!getenv("LD_BIND_LAZY")) { setenv("LD_BIND_NOW", "1", 1); } /* Set sane defaults for ASAN if nothing else specified. */ - if (fsrv->debug == true && !getenv("ASAN_OPTIONS")) + if (!getenv("ASAN_OPTIONS")) setenv("ASAN_OPTIONS", "abort_on_error=1:" "detect_leaks=0:" @@ -498,11 +498,11 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "handle_abort=0:" "handle_sigfpe=0:" "handle_sigill=0", - 0); + 1); /* Set sane defaults for UBSAN if nothing else specified. */ - if (fsrv->debug == true && !getenv("UBSAN_OPTIONS")) + if (!getenv("UBSAN_OPTIONS")) setenv("UBSAN_OPTIONS", "halt_on_error=1:" "abort_on_error=1:" @@ -514,7 +514,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "handle_abort=0:" "handle_sigfpe=0:" "handle_sigill=0", - 0); + 1); /* Envs for QASan */ setenv("QASAN_MAX_CALL_STACK", "0", 0); @@ -523,7 +523,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, /* MSAN is tricky, because it doesn't support abort_on_error=1 at this point. So, we do this in a very hacky way. */ - if (fsrv->debug == true && !getenv("MSAN_OPTIONS")) + if (!getenv("MSAN_OPTIONS")) setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":" "symbolize=0:" @@ -536,7 +536,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "handle_abort=0:" "handle_sigfpe=0:" "handle_sigill=0", - 0); + 1); fsrv->init_child_func(fsrv, argv); @@ -931,7 +931,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "%s" - " - Most likely the target has a huge coverage map, retry with setting the\n" + " - Most likely the target has a huge coverage map, retry with " + "setting the\n" " environment variable AFL_MAP_SIZE=4194304\n\n" " - The current memory limit (%s) is too restrictive, causing an " diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 3dbc4c65..2d5f32a7 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2457,7 +2457,7 @@ void check_asan_opts(afl_state_t *afl) { } - if (!strstr(x, "symbolize=0")) { + if (!afl->debug && !strstr(x, "symbolize=0")) { FATAL("Custom MSAN_OPTIONS set without symbolize=0 - please fix!"); -- cgit v1.2.3 From 47f2650a32470172a32c4ebd446003cb8a4b80e8 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 9 Mar 2021 16:53:56 +0100 Subject: add AFL_NOOPT --- src/afl-cc.c | 21 +++++++++++++++++++-- src/afl-common.c | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index bb136fb9..8f9bb397 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1025,7 +1025,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { int main(int argc, char **argv, char **envp) { - int i; + int i, passthrough = 0; char *callname = argv[0], *ptr = NULL; if (getenv("AFL_DEBUG")) { @@ -1045,6 +1045,13 @@ int main(int argc, char **argv, char **envp) { } + if (getenv("AFL_PASSTHROUGH") || getenv("AFL_NOOPT")) { + + passthrough = 1; + if (!debug) { be_quiet = 1; } + + } + if ((ptr = strrchr(callname, '/')) != NULL) callname = ptr + 1; argvnull = (u8 *)argv[0]; check_environment_vars(envp); @@ -1665,6 +1672,7 @@ int main(int argc, char **argv, char **envp) { " AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" " AFL_NO_BUILTIN: no builtins for string compare functions (for " "libtokencap.so)\n" + " AFL_NOOP: behave lik a normal compiler (to pass configure tests)\n" " AFL_PATH: path to instrumenting pass and runtime " "(afl-compiler-rt.*o)\n" " AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n" @@ -1977,7 +1985,16 @@ int main(int argc, char **argv, char **envp) { } - execvp(cc_params[0], (char **)cc_params); + if (passthrough) { + + argv[0] = cc_params[0]; + execvp(cc_params[0], (char **)argv); + + } else { + + execvp(cc_params[0], (char **)cc_params); + + } FATAL("Oops, failed to execute '%s' - check your PATH", cc_params[0]); diff --git a/src/afl-common.c b/src/afl-common.c index a306fe5e..68f82a5e 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -682,6 +682,7 @@ void check_environment_vars(char **envp) { env[strlen(afl_environment_variables[i])] == '=') { match = 1; + if ((val = getenv(afl_environment_variables[i])) && !*val) { WARNF( -- cgit v1.2.3 From 0868ea8348ebc682c370d763324b49536ee4c1f7 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 9 Mar 2021 17:15:19 +0100 Subject: fix compiler rt on -c --- src/afl-cc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 8f9bb397..a517124f 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -940,7 +940,10 @@ static void edit_params(u32 argc, char **argv, char **envp) { } - if (preprocessor_only) { + // prevent unnecessary build errors + cc_params[cc_par_cnt++] = "-Wno-unused-command-line-argument"; + + if (preprocessor_only || have_c) { /* In the preprocessor_only case (-E), we are not actually compiling at all but requesting the compiler to output preprocessed sources only. @@ -1001,18 +1004,15 @@ static void edit_params(u32 argc, char **argv, char **envp) { } #if !defined(__APPLE__) && !defined(__sun) - if (!shared_linking && !have_c) + if (!shared_linking) cc_params[cc_par_cnt++] = alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); #endif #if defined(USEMMAP) && !defined(__HAIKU__) - if (!have_c) cc_params[cc_par_cnt++] = "-lrt"; + cc_params[cc_par_cnt++] = "-lrt"; #endif - // prevent unnecessary build errors - cc_params[cc_par_cnt++] = "-Wno-unused-command-line-argument"; - } #endif -- cgit v1.2.3 From 791c5c171d9e4e7391a9c3760a4a8eb4ce2b4058 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 9 Mar 2021 18:44:42 +0100 Subject: fix ctx-1 --- src/afl-cc.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index a517124f..b9e0c101 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1298,11 +1298,21 @@ int main(int argc, char **argv, char **envp) { if (getenv("AFL_LLVM_CTX_K")) { - instrument_opt_mode |= INSTRUMENT_OPT_CTX_K; ctx_k = atoi(getenv("AFL_LLVM_CTX_K")); if (ctx_k < 1 || ctx_k > CTX_MAX_K) FATAL("K-CTX instrumentation mode must be between 1 and CTX_MAX_K (%u)", CTX_MAX_K); + if (ctx_k == 1) { + + setenv("AFL_LLVM_CALLER", "1", 1); + unsetenv("AFL_LLVM_CTX_K"); + instrument_opt_mode |= INSTRUMENT_OPT_CALLER; + + } else { + + instrument_opt_mode |= INSTRUMENT_OPT_CTX_K; + + } } @@ -1422,9 +1432,20 @@ int main(int argc, char **argv, char **envp) { "K-CTX instrumentation option must be between 1 and CTX_MAX_K " "(%u)", CTX_MAX_K); - instrument_opt_mode |= (INSTRUMENT_OPT_CTX_K); - u8 *ptr4 = alloc_printf("%u", ctx_k); - setenv("AFL_LLVM_CTX_K", ptr4, 1); + + if (ctx_k == 1) { + + instrument_opt_mode |= INSTRUMENT_OPT_CALLER; + setenv("AFL_LLVM_CALLER", "1", 1); + unsetenv("AFL_LLVM_CTX_K"); + + } else { + + instrument_opt_mode |= (INSTRUMENT_OPT_CTX_K); + u8 *ptr4 = alloc_printf("%u", ctx_k); + setenv("AFL_LLVM_CTX_K", ptr4, 1); + + } } -- cgit v1.2.3 From 5fab0fa51f14d8770b48501e93cde38d97175e4e Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Tue, 9 Mar 2021 18:31:15 +0000 Subject: setting general schedule priority for performance on Mac. --- src/afl-fuzz.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 09aff4fb..9c822d43 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1403,6 +1403,14 @@ int main(int argc, char **argv_orig, char **envp) { set_scheduler_mode(SCHEDULER_MODE_LOW_LATENCY); #endif + #ifdef __APPLE__ + if (pthread_set_qos_class_self_np(QOS_CLASS_USER_INTERACTIVE, 0) != 0) { + + WARNF("general thread priority settings failed"); + + } + #endif + init_count_class16(); if (afl->is_main_node && check_main_node_exists(afl) == 1) { -- cgit v1.2.3 From f21a5c42c150fa48099144b937d5ec48fdc7048b Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 10 Mar 2021 00:55:26 +0100 Subject: tiny typo fixed --- src/afl-cc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index b9e0c101..49de08e7 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1693,7 +1693,7 @@ int main(int argc, char **argv, char **envp) { " AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" " AFL_NO_BUILTIN: no builtins for string compare functions (for " "libtokencap.so)\n" - " AFL_NOOP: behave lik a normal compiler (to pass configure tests)\n" + " AFL_NOOP: behave like a normal compiler (to pass configure tests)\n" " AFL_PATH: path to instrumenting pass and runtime " "(afl-compiler-rt.*o)\n" " AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n" -- cgit v1.2.3 From 851231c846ab4c9fe121f78a5677fa8820e843f3 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 10 Mar 2021 01:15:38 +0100 Subject: fixed scan-build warnings --- src/afl-cc.c | 3 ++- src/afl-fuzz-init.c | 13 +++++++------ src/afl-fuzz.c | 1 + 3 files changed, 10 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 49de08e7..44654de0 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1693,7 +1693,8 @@ int main(int argc, char **argv, char **envp) { " AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" " AFL_NO_BUILTIN: no builtins for string compare functions (for " "libtokencap.so)\n" - " AFL_NOOP: behave like a normal compiler (to pass configure tests)\n" + " AFL_NOOP: behave like a normal compiler (to pass configure " + "tests)\n" " AFL_PATH: path to instrumenting pass and runtime " "(afl-compiler-rt.*o)\n" " AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n" diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 2d5f32a7..ca2f75f1 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -828,7 +828,7 @@ void perform_dry_run(afl_state_t *afl) { for (idx = 0; idx < afl->queued_paths; idx++) { q = afl->queue_buf[idx]; - if (unlikely(q->disabled)) { continue; } + if (unlikely(!q || q->disabled)) { continue; } u8 res; s32 fd; @@ -1069,7 +1069,7 @@ void perform_dry_run(afl_state_t *afl) { } afl->max_depth = 0; - for (i = 0; i < afl->queued_paths; i++) { + for (i = 0; i < afl->queued_paths && likely(afl->queue_buf[i]); i++) { if (!afl->queue_buf[i]->disabled && afl->queue_buf[i]->depth > afl->max_depth) @@ -1136,10 +1136,11 @@ void perform_dry_run(afl_state_t *afl) { for (idx = 0; idx < afl->queued_paths; idx++) { q = afl->queue_buf[idx]; - if (q->disabled || q->cal_failed || !q->exec_cksum) { continue; } + if (!q || q->disabled || q->cal_failed || !q->exec_cksum) { continue; } u32 done = 0; - for (i = idx + 1; i < afl->queued_paths && !done; i++) { + for (i = idx + 1; + i < afl->queued_paths && !done && likely(afl->queue_buf[i]); i++) { struct queue_entry *p = afl->queue_buf[i]; if (p->disabled || p->cal_failed || !p->exec_cksum) { continue; } @@ -1191,7 +1192,7 @@ void perform_dry_run(afl_state_t *afl) { for (idx = 0; idx < afl->queued_paths; idx++) { - if (!afl->queue_buf[idx]->disabled && + if (afl->queue_buf[idx] && !afl->queue_buf[idx]->disabled && afl->queue_buf[idx]->depth > afl->max_depth) afl->max_depth = afl->queue_buf[idx]->depth; @@ -1247,7 +1248,7 @@ void pivot_inputs(afl_state_t *afl) { ACTF("Creating hard links for all input files..."); - for (i = 0; i < afl->queued_paths; i++) { + for (i = 0; i < afl->queued_paths && likely(afl->queue_buf[i]); i++) { q = afl->queue_buf[i]; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 9c822d43..065010fa 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1409,6 +1409,7 @@ int main(int argc, char **argv_orig, char **envp) { WARNF("general thread priority settings failed"); } + #endif init_count_class16(); -- cgit v1.2.3 From a0c30116733dd08e8d74a879c0e99be140b7eebb Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 10 Mar 2021 11:08:03 +0100 Subject: change map_size tests --- src/afl-forkserver.c | 8 ++++---- src/afl-fuzz.c | 30 +++++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 82ec3069..68995388 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -821,7 +821,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, " - The target binary requires a large map and crashes before " "reporting.\n" - " Set a high value (e.g. AFL_MAP_SIZE=1024000) or use " + " Set a high value (e.g. AFL_MAP_SIZE=8000000) or use " "AFL_DEBUG=1 to see the\n" " message from the target binary\n\n" @@ -848,7 +848,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, " - The target binary requires a large map and crashes before " "reporting.\n" - " Set a high value (e.g. AFL_MAP_SIZE=1024000) or use " + " Set a high value (e.g. AFL_MAP_SIZE=8000000) or use " "AFL_DEBUG=1 to see the\n" " message from the target binary\n\n" @@ -914,7 +914,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, "handshake with the injected code.\n" "Most likely the target has a huge coverage map, retry with setting" " the\n" - "environment variable AFL_MAP_SIZE=4194304\n" + "environment variable AFL_MAP_SIZE=8000000\n" "Otherwise there is a horrible bug in the fuzzer.\n" "Poke for troubleshooting tips.\n"); @@ -933,7 +933,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, " - Most likely the target has a huge coverage map, retry with " "setting the\n" - " environment variable AFL_MAP_SIZE=4194304\n\n" + " environment variable AFL_MAP_SIZE=8000000\n\n" " - The current memory limit (%s) is too restrictive, causing an " "OOM\n" diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 065010fa..8364c1c2 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1569,13 +1569,21 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->non_instrumented_mode && !afl->fsrv.qemu_mode && !afl->unicorn_mode) { - afl->fsrv.map_size = 4194304; // dummy temporary value - setenv("AFL_MAP_SIZE", "4194304", 1); + u32 set_env = 0; + if (!getenv("AFL_MAP_SIZE")) { + + afl->fsrv.map_size = 8000000; // dummy temporary value + setenv("AFL_MAP_SIZE", "8000000", 1); + set_env = 1; + + } + + u32 prev_map_size = afl->fsrv.map_size; u32 new_map_size = afl_fsrv_get_mapsize( &afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); - if (new_map_size && new_map_size != 4194304) { + if (new_map_size && new_map_size != prev_map_size) { // only reinitialize when it makes sense if (map_size < new_map_size || @@ -1607,6 +1615,7 @@ int main(int argc, char **argv_orig, char **envp) { } map_size = new_map_size; + if (set_env) { unsetenv("AFL_MAP_SIZE"); } } @@ -1624,13 +1633,22 @@ int main(int argc, char **argv_orig, char **envp) { afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary; afl->cmplog_fsrv.init_child_func = cmplog_exec_child; - afl->cmplog_fsrv.map_size = 4194304; + u32 set_env = 0; + if (!getenv("AFL_MAP_SIZE")) { + + afl->fsrv.map_size = 8000000; // dummy temporary value + setenv("AFL_MAP_SIZE", "8000000", 1); + set_env = 1; + + } + + u32 prev_map_size = afl->fsrv.map_size; u32 new_map_size = afl_fsrv_get_mapsize(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); - if (new_map_size && new_map_size != 4194304) { + if (new_map_size && new_map_size != prev_map_size) { // only reinitialize when it needs to be larger if (map_size < new_map_size) { @@ -1667,6 +1685,8 @@ int main(int argc, char **argv_orig, char **envp) { } + if (set_env) { unsetenv("AFL_MAP_SIZE"); } + } afl->cmplog_fsrv.map_size = map_size; -- cgit v1.2.3 From a10a627622fe9785301fcb033cd1eee69d3f3056 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 10 Mar 2021 19:22:57 +0100 Subject: fix auto map discovery --- src/afl-common.c | 4 +- src/afl-fuzz.c | 181 ++++++++++++++++++++++++++----------------------------- 2 files changed, 86 insertions(+), 99 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 68f82a5e..9f6eb564 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -1123,7 +1123,7 @@ u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) { /* Reads the map size from ENV */ u32 get_map_size(void) { - uint32_t map_size = (MAP_SIZE << 2); // needed for target ctors :( + uint32_t map_size = 8000000; // a very large default map char * ptr; if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) { @@ -1131,7 +1131,7 @@ u32 get_map_size(void) { map_size = atoi(ptr); if (!map_size || map_size > (1 << 29)) { - FATAL("illegal AFL_MAP_SIZE %u, must be between %u and %u", map_size, 32U, + FATAL("illegal AFL_MAP_SIZE %u, must be between %u and %u", map_size, 64U, 1U << 29); } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 8364c1c2..cd049fd5 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -351,7 +351,7 @@ int main(int argc, char **argv_orig, char **envp) { exit_1 = !!afl->afl_env.afl_bench_just_one; SAYF(cCYA "afl-fuzz" VERSION cRST - " based on afl by Michal Zalewski and a big online community\n"); + " based on afl by Michal Zalewski and a large online community\n"); doc_path = access(DOC_PATH, F_OK) != 0 ? (u8 *)"docs" : (u8 *)DOC_PATH; @@ -1562,62 +1562,63 @@ int main(int argc, char **argv_orig, char **envp) { } - afl->argv = use_argv; - afl->fsrv.trace_bits = - afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode); - - if (!afl->non_instrumented_mode && !afl->fsrv.qemu_mode && - !afl->unicorn_mode) { - - u32 set_env = 0; - if (!getenv("AFL_MAP_SIZE")) { - - afl->fsrv.map_size = 8000000; // dummy temporary value - setenv("AFL_MAP_SIZE", "8000000", 1); - set_env = 1; - - } - - u32 prev_map_size = afl->fsrv.map_size; + if (afl->non_instrumented_mode || afl->fsrv.qemu_mode || afl->unicorn_mode) { - u32 new_map_size = afl_fsrv_get_mapsize( - &afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); + map_size = afl->fsrv.map_size = MAP_SIZE; + afl->virgin_bits = ck_realloc(afl->virgin_bits, map_size); + afl->virgin_tmout = ck_realloc(afl->virgin_tmout, map_size); + afl->virgin_crash = ck_realloc(afl->virgin_crash, map_size); + afl->var_bytes = ck_realloc(afl->var_bytes, map_size); + afl->top_rated = ck_realloc(afl->top_rated, map_size * sizeof(void *)); + afl->clean_trace = ck_realloc(afl->clean_trace, map_size); + afl->clean_trace_custom = ck_realloc(afl->clean_trace_custom, map_size); + afl->first_trace = ck_realloc(afl->first_trace, map_size); + afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, map_size); - if (new_map_size && new_map_size != prev_map_size) { - - // only reinitialize when it makes sense - if (map_size < new_map_size || - (new_map_size > map_size && new_map_size - map_size > MAP_SIZE)) { + } - OKF("Re-initializing maps to %u bytes", new_map_size); + afl->argv = use_argv; + afl->fsrv.trace_bits = + afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode); - afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size); - afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); - afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); - afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size); - afl->top_rated = - ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); - afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size); - afl->clean_trace_custom = - ck_realloc(afl->clean_trace_custom, new_map_size); - afl->first_trace = ck_realloc(afl->first_trace, new_map_size); - afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); + if (afl->fsrv.map_size <= 8000000) { - afl_fsrv_kill(&afl->fsrv); - afl_shm_deinit(&afl->shm); - afl->fsrv.map_size = new_map_size; - afl->fsrv.trace_bits = - afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); - setenv("AFL_NO_AUTODICT", "1", 1); // loaded already - afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, - afl->afl_env.afl_debug_child); + afl->fsrv.map_size = 8000000; // dummy temporary value + setenv("AFL_MAP_SIZE", "8000000", 1); - } + } - map_size = new_map_size; - if (set_env) { unsetenv("AFL_MAP_SIZE"); } + u32 new_map_size = afl_fsrv_get_mapsize( + &afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); + + // only reinitialize when it makes sense + if (map_size < new_map_size || + (new_map_size > map_size && new_map_size - map_size > MAP_SIZE && + (!afl->cmplog_binary || new_map_size == MAP_SIZE))) { + + OKF("Re-initializing maps to %u bytes", new_map_size); + + afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size); + afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); + afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); + afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size); + afl->top_rated = ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); + afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size); + afl->clean_trace_custom = ck_realloc(afl->clean_trace_custom, new_map_size); + afl->first_trace = ck_realloc(afl->first_trace, new_map_size); + afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); + + afl_fsrv_kill(&afl->fsrv); + afl_shm_deinit(&afl->shm); + afl->fsrv.map_size = new_map_size; + afl->fsrv.trace_bits = + afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); + setenv("AFL_NO_AUTODICT", "1", 1); // loaded already + afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, + afl->afl_env.afl_debug_child); + map_size = new_map_size; - } + } else { afl->fsrv.map_size = map_size; @@ -1633,64 +1634,50 @@ int main(int argc, char **argv_orig, char **envp) { afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary; afl->cmplog_fsrv.init_child_func = cmplog_exec_child; - u32 set_env = 0; - if (!getenv("AFL_MAP_SIZE")) { - - afl->fsrv.map_size = 8000000; // dummy temporary value - setenv("AFL_MAP_SIZE", "8000000", 1); - set_env = 1; - - } - - u32 prev_map_size = afl->fsrv.map_size; - u32 new_map_size = afl_fsrv_get_mapsize(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); - if (new_map_size && new_map_size != prev_map_size) { - - // only reinitialize when it needs to be larger - if (map_size < new_map_size) { - - OKF("Re-initializing maps to %u bytes due cmplog", new_map_size); + // only reinitialize when necessary + if (map_size < new_map_size || + (new_map_size > map_size && new_map_size - map_size > MAP_SIZE)) { + + OKF("Re-initializing maps to %u bytes due cmplog", new_map_size); + + afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size); + afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); + afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); + afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size); + afl->top_rated = + ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); + afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size); + afl->clean_trace_custom = + ck_realloc(afl->clean_trace_custom, new_map_size); + afl->first_trace = ck_realloc(afl->first_trace, new_map_size); + afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); + + afl_fsrv_kill(&afl->fsrv); + afl_fsrv_kill(&afl->cmplog_fsrv); + afl_shm_deinit(&afl->shm); + afl->cmplog_fsrv.map_size = new_map_size; // non-cmplog stays the same + + afl->fsrv.trace_bits = + afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); + setenv("AFL_NO_AUTODICT", "1", 1); // loaded already + afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, + afl->afl_env.afl_debug_child); + + afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, + afl->afl_env.afl_debug_child); - afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size); - afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); - afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); - afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size); - afl->top_rated = - ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); - afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size); - afl->clean_trace_custom = - ck_realloc(afl->clean_trace_custom, new_map_size); - afl->first_trace = ck_realloc(afl->first_trace, new_map_size); - afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); - - afl_fsrv_kill(&afl->fsrv); - afl_fsrv_kill(&afl->cmplog_fsrv); - afl_shm_deinit(&afl->shm); - afl->cmplog_fsrv.map_size = new_map_size; // non-cmplog stays the same - - afl->fsrv.trace_bits = - afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); - setenv("AFL_NO_AUTODICT", "1", 1); // loaded already - afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, - afl->afl_env.afl_debug_child); - - afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, - afl->afl_env.afl_debug_child); - - map_size = new_map_size; + map_size = new_map_size; - } + } else { - if (set_env) { unsetenv("AFL_MAP_SIZE"); } + afl->cmplog_fsrv.map_size = map_size; } - afl->cmplog_fsrv.map_size = map_size; - OKF("Cmplog forkserver successfully started"); } -- cgit v1.2.3 From 16e3e2a7f78a11702fb394803bec78b3b0a99906 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 11 Mar 2021 01:39:21 +0100 Subject: implemented #801 --- src/afl-fuzz-stats.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index bd856088..2e7de7b3 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -823,7 +823,12 @@ void show_stats(afl_state_t *afl) { SAYF(bV bSTOP " total execs : " cRST "%-20s " bSTG bV bSTOP " total crashes : %s%-22s" bSTG bV "\n", u_stringify_int(IB(0), afl->fsrv.total_execs), - afl->unique_crashes ? cLRD : cRST, tmp); + // New crashes this round -> Red, restored crashes -> yellow, else + // white. + afl->total_crashes ? cLRD + : afl->unique_crashes ? cYEL + : cRST, + tmp); } -- cgit v1.2.3 From adeb0d18b12e717fe866e1790a522b4f158f11e1 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 11 Mar 2021 08:59:26 +0100 Subject: fix the auto map fix --- src/afl-fuzz.c | 159 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 90 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index cd049fd5..096ee29d 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1581,46 +1581,58 @@ int main(int argc, char **argv_orig, char **envp) { afl->fsrv.trace_bits = afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode); - if (afl->fsrv.map_size <= 8000000) { + if (!afl->non_instrumented_mode && !afl->fsrv.qemu_mode && + !afl->unicorn_mode) { - afl->fsrv.map_size = 8000000; // dummy temporary value - setenv("AFL_MAP_SIZE", "8000000", 1); + if (map_size <= 8000000&& !afl->non_instrumented_mode && + !afl->fsrv.qemu_mode && !afl->unicorn_mode) { - } + afl->fsrv.map_size = 8000000; // dummy temporary value + setenv("AFL_MAP_SIZE", "8000000", 1); - u32 new_map_size = afl_fsrv_get_mapsize( - &afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); - - // only reinitialize when it makes sense - if (map_size < new_map_size || - (new_map_size > map_size && new_map_size - map_size > MAP_SIZE && - (!afl->cmplog_binary || new_map_size == MAP_SIZE))) { - - OKF("Re-initializing maps to %u bytes", new_map_size); - - afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size); - afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); - afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); - afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size); - afl->top_rated = ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); - afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size); - afl->clean_trace_custom = ck_realloc(afl->clean_trace_custom, new_map_size); - afl->first_trace = ck_realloc(afl->first_trace, new_map_size); - afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); - - afl_fsrv_kill(&afl->fsrv); - afl_shm_deinit(&afl->shm); - afl->fsrv.map_size = new_map_size; - afl->fsrv.trace_bits = - afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); - setenv("AFL_NO_AUTODICT", "1", 1); // loaded already - afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, - afl->afl_env.afl_debug_child); - map_size = new_map_size; + } - } else { + u32 new_map_size = afl_fsrv_get_mapsize( + &afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); + + if (new_map_size && new_map_size != map_size) { + + // only reinitialize when it makes sense + if (map_size < new_map_size || + (new_map_size > map_size && new_map_size - map_size > MAP_SIZE)) { + + OKF("Re-initializing maps to %u bytes", new_map_size); + + afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size); + afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); + afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); + afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size); + afl->top_rated = + ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); + afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size); + afl->clean_trace_custom = + ck_realloc(afl->clean_trace_custom, new_map_size); + afl->first_trace = ck_realloc(afl->first_trace, new_map_size); + afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); + + afl_fsrv_kill(&afl->fsrv); + afl_shm_deinit(&afl->shm); + afl->fsrv.map_size = new_map_size; + afl->fsrv.trace_bits = + afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); + setenv("AFL_NO_AUTODICT", "1", 1); // loaded already + afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, + afl->afl_env.afl_debug_child); - afl->fsrv.map_size = map_size; + } + + map_size = new_map_size; + + } else { + + afl->fsrv.map_size = map_size; + + } } @@ -1634,50 +1646,59 @@ int main(int argc, char **argv_orig, char **envp) { afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary; afl->cmplog_fsrv.init_child_func = cmplog_exec_child; + if (map_size <= 8000000 && !afl->non_instrumented_mode && + !afl->fsrv.qemu_mode && !afl->unicorn_mode) { + + afl->fsrv.map_size = 8000000; // dummy temporary value + setenv("AFL_MAP_SIZE", "8000000", 1); + + } + u32 new_map_size = afl_fsrv_get_mapsize(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); - // only reinitialize when necessary - if (map_size < new_map_size || - (new_map_size > map_size && new_map_size - map_size > MAP_SIZE)) { - - OKF("Re-initializing maps to %u bytes due cmplog", new_map_size); - - afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size); - afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); - afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); - afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size); - afl->top_rated = - ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); - afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size); - afl->clean_trace_custom = - ck_realloc(afl->clean_trace_custom, new_map_size); - afl->first_trace = ck_realloc(afl->first_trace, new_map_size); - afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); - - afl_fsrv_kill(&afl->fsrv); - afl_fsrv_kill(&afl->cmplog_fsrv); - afl_shm_deinit(&afl->shm); - afl->cmplog_fsrv.map_size = new_map_size; // non-cmplog stays the same - - afl->fsrv.trace_bits = - afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); - setenv("AFL_NO_AUTODICT", "1", 1); // loaded already - afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, - afl->afl_env.afl_debug_child); - - afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, - afl->afl_env.afl_debug_child); + if (new_map_size && new_map_size != map_size) { - map_size = new_map_size; + // only reinitialize when it needs to be larger + if (map_size < new_map_size) { - } else { + OKF("Re-initializing maps to %u bytes due cmplog", new_map_size); + + afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size); + afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); + afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); + afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size); + afl->top_rated = + ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); + afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size); + afl->clean_trace_custom = + ck_realloc(afl->clean_trace_custom, new_map_size); + afl->first_trace = ck_realloc(afl->first_trace, new_map_size); + afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); + + afl_fsrv_kill(&afl->fsrv); + afl_fsrv_kill(&afl->cmplog_fsrv); + afl_shm_deinit(&afl->shm); + afl->cmplog_fsrv.map_size = new_map_size; // non-cmplog stays the same - afl->cmplog_fsrv.map_size = map_size; + afl->fsrv.trace_bits = + afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); + setenv("AFL_NO_AUTODICT", "1", 1); // loaded already + afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, + afl->afl_env.afl_debug_child); + + afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, + afl->afl_env.afl_debug_child); + + } + + map_size = new_map_size; } + afl->cmplog_fsrv.map_size = map_size; + OKF("Cmplog forkserver successfully started"); } -- cgit v1.2.3 From b7d90a9e318933211936be8f5174690cd8c01e24 Mon Sep 17 00:00:00 2001 From: aflpp Date: Thu, 11 Mar 2021 09:32:22 +0100 Subject: new auto map --- src/afl-fuzz.c | 130 +++++++++++++++++++++++++++------------------------------ 1 file changed, 61 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 096ee29d..dbf4df37 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1584,7 +1584,7 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->non_instrumented_mode && !afl->fsrv.qemu_mode && !afl->unicorn_mode) { - if (map_size <= 8000000&& !afl->non_instrumented_mode && + if (map_size <= 8000000 && !afl->non_instrumented_mode && !afl->fsrv.qemu_mode && !afl->unicorn_mode) { afl->fsrv.map_size = 8000000; // dummy temporary value @@ -1595,45 +1595,40 @@ int main(int argc, char **argv_orig, char **envp) { u32 new_map_size = afl_fsrv_get_mapsize( &afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); - if (new_map_size && new_map_size != map_size) { - - // only reinitialize when it makes sense - if (map_size < new_map_size || - (new_map_size > map_size && new_map_size - map_size > MAP_SIZE)) { - - OKF("Re-initializing maps to %u bytes", new_map_size); - - afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size); - afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); - afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); - afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size); - afl->top_rated = - ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); - afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size); - afl->clean_trace_custom = - ck_realloc(afl->clean_trace_custom, new_map_size); - afl->first_trace = ck_realloc(afl->first_trace, new_map_size); - afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); - - afl_fsrv_kill(&afl->fsrv); - afl_shm_deinit(&afl->shm); - afl->fsrv.map_size = new_map_size; - afl->fsrv.trace_bits = - afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); - setenv("AFL_NO_AUTODICT", "1", 1); // loaded already - afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, - afl->afl_env.afl_debug_child); - - } + // only reinitialize when it makes sense + if (map_size < new_map_size || + (!afl->cmplog_binary && new_map_size < map_size && + map_size - new_map_size > MAP_SIZE)) { + + OKF("Re-initializing maps to %u bytes", new_map_size); + + afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size); + afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); + afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); + afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size); + afl->top_rated = + ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); + afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size); + afl->clean_trace_custom = + ck_realloc(afl->clean_trace_custom, new_map_size); + afl->first_trace = ck_realloc(afl->first_trace, new_map_size); + afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); + + afl_fsrv_kill(&afl->fsrv); + afl_shm_deinit(&afl->shm); + afl->fsrv.map_size = new_map_size; + afl->fsrv.trace_bits = + afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); + setenv("AFL_NO_AUTODICT", "1", 1); // loaded already + afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, + afl->afl_env.afl_debug_child); map_size = new_map_size; - } else { - - afl->fsrv.map_size = map_size; - } + afl->fsrv.map_size = map_size; + } if (afl->cmplog_binary) { @@ -1658,40 +1653,37 @@ int main(int argc, char **argv_orig, char **envp) { afl_fsrv_get_mapsize(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); - if (new_map_size && new_map_size != map_size) { - - // only reinitialize when it needs to be larger - if (map_size < new_map_size) { - - OKF("Re-initializing maps to %u bytes due cmplog", new_map_size); - - afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size); - afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); - afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); - afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size); - afl->top_rated = - ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); - afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size); - afl->clean_trace_custom = - ck_realloc(afl->clean_trace_custom, new_map_size); - afl->first_trace = ck_realloc(afl->first_trace, new_map_size); - afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); - - afl_fsrv_kill(&afl->fsrv); - afl_fsrv_kill(&afl->cmplog_fsrv); - afl_shm_deinit(&afl->shm); - afl->cmplog_fsrv.map_size = new_map_size; // non-cmplog stays the same - - afl->fsrv.trace_bits = - afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); - setenv("AFL_NO_AUTODICT", "1", 1); // loaded already - afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, - afl->afl_env.afl_debug_child); - - afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, - afl->afl_env.afl_debug_child); - - } + // only reinitialize when it needs to be larger + if (map_size < new_map_size || + (new_map_size < map_size && map_size - new_map_size > MAP_SIZE)) { + + OKF("Re-initializing maps to %u bytes due cmplog", new_map_size); + + afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size); + afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); + afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); + afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size); + afl->top_rated = + ck_realloc(afl->top_rated, new_map_size * sizeof(void *)); + afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size); + afl->clean_trace_custom = + ck_realloc(afl->clean_trace_custom, new_map_size); + afl->first_trace = ck_realloc(afl->first_trace, new_map_size); + afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); + + afl_fsrv_kill(&afl->fsrv); + afl_fsrv_kill(&afl->cmplog_fsrv); + afl_shm_deinit(&afl->shm); + afl->cmplog_fsrv.map_size = new_map_size; // non-cmplog stays the same + + afl->fsrv.trace_bits = + afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); + setenv("AFL_NO_AUTODICT", "1", 1); // loaded already + afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, + afl->afl_env.afl_debug_child); + + afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, + afl->afl_env.afl_debug_child); map_size = new_map_size; -- cgit v1.2.3 From 8ff5063545aeed101105a63d40d0b068af6c9ec1 Mon Sep 17 00:00:00 2001 From: aflpp Date: Thu, 11 Mar 2021 18:03:18 +0100 Subject: fix --- src/afl-fuzz.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index dbf4df37..7fe89c11 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1596,9 +1596,9 @@ int main(int argc, char **argv_orig, char **envp) { &afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); // only reinitialize when it makes sense - if (map_size < new_map_size || - (!afl->cmplog_binary && new_map_size < map_size && - map_size - new_map_size > MAP_SIZE)) { + if ((map_size < new_map_size || + (new_map_size != MAP_SIZE && new_map_size < map_size && + map_size - new_map_size > MAP_SIZE))) { OKF("Re-initializing maps to %u bytes", new_map_size); @@ -1644,7 +1644,7 @@ int main(int argc, char **argv_orig, char **envp) { if (map_size <= 8000000 && !afl->non_instrumented_mode && !afl->fsrv.qemu_mode && !afl->unicorn_mode) { - afl->fsrv.map_size = 8000000; // dummy temporary value + afl->cmplog_fsrv.map_size = 8000000; // dummy temporary value setenv("AFL_MAP_SIZE", "8000000", 1); } @@ -1654,8 +1654,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->afl_env.afl_debug_child); // only reinitialize when it needs to be larger - if (map_size < new_map_size || - (new_map_size < map_size && map_size - new_map_size > MAP_SIZE)) { + if (map_size < new_map_size) { OKF("Re-initializing maps to %u bytes due cmplog", new_map_size); @@ -1674,22 +1673,23 @@ int main(int argc, char **argv_orig, char **envp) { afl_fsrv_kill(&afl->fsrv); afl_fsrv_kill(&afl->cmplog_fsrv); afl_shm_deinit(&afl->shm); + afl->cmplog_fsrv.map_size = new_map_size; // non-cmplog stays the same + map_size = new_map_size; + setenv("AFL_NO_AUTODICT", "1", 1); // loaded already afl->fsrv.trace_bits = afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); - setenv("AFL_NO_AUTODICT", "1", 1); // loaded already afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); - afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); - map_size = new_map_size; + } else { - } + afl->cmplog_fsrv.map_size = new_map_size; - afl->cmplog_fsrv.map_size = map_size; + } OKF("Cmplog forkserver successfully started"); -- cgit v1.2.3 From d32b1d6b0c03cfc223c26c9af661c2592469a0de Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 12 Mar 2021 03:46:50 +0100 Subject: unique crashes yellow on resume (#801) --- src/afl-fuzz-stats.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 2e7de7b3..99059a2d 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -645,6 +645,13 @@ void show_stats(afl_state_t *afl) { #define SP10 SP5 SP5 #define SP20 SP10 SP10 + /* Since `total_crashes` does not get reloaded from disk on restart, + it indicates if we found crashes this round already -> paint red. + If it's 0, but `unique_crashes` is set from a past run, paint in yellow. */ + char *crash_color = afl->total_crashes ? cLRD + : afl->unique_crashes ? cYEL + : cRST; + /* Lord, forgive me this. */ SAYF(SET_G1 bSTG bLT bH bSTOP cCYA @@ -732,7 +739,7 @@ void show_stats(afl_state_t *afl) { u_stringify_time_diff(time_tmp, cur_ms, afl->last_crash_time); SAYF(bV bSTOP " last uniq crash : " cRST "%-33s " bSTG bV bSTOP " uniq crashes : %s%-6s" bSTG bV "\n", - time_tmp, afl->unique_crashes ? cLRD : cRST, tmp); + time_tmp, crash_color, tmp); sprintf(tmp, "%s%s", u_stringify_int(IB(0), afl->unique_hangs), (afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : ""); @@ -815,20 +822,13 @@ void show_stats(afl_state_t *afl) { SAYF(bV bSTOP " total execs : " cRST "%-20s " bSTG bV bSTOP " new crashes : %s%-22s" bSTG bV "\n", - u_stringify_int(IB(0), afl->fsrv.total_execs), - afl->unique_crashes ? cLRD : cRST, tmp); + u_stringify_int(IB(0), afl->fsrv.total_execs), crash_color, tmp); } else { SAYF(bV bSTOP " total execs : " cRST "%-20s " bSTG bV bSTOP " total crashes : %s%-22s" bSTG bV "\n", - u_stringify_int(IB(0), afl->fsrv.total_execs), - // New crashes this round -> Red, restored crashes -> yellow, else - // white. - afl->total_crashes ? cLRD - : afl->unique_crashes ? cYEL - : cRST, - tmp); + u_stringify_int(IB(0), afl->fsrv.total_execs), crash_color, tmp); } -- cgit v1.2.3 From 3753f56c254ac96023fbc295777b13d80a7a9d31 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 12 Mar 2021 03:47:12 +0100 Subject: make get_offsets executable --- src/afl-fuzz.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 7fe89c11..ff27048a 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1597,8 +1597,8 @@ int main(int argc, char **argv_orig, char **envp) { // only reinitialize when it makes sense if ((map_size < new_map_size || - (new_map_size != MAP_SIZE && new_map_size < map_size && - map_size - new_map_size > MAP_SIZE))) { + (new_map_size != MAP_SIZE && new_map_size < map_size && + map_size - new_map_size > MAP_SIZE))) { OKF("Re-initializing maps to %u bytes", new_map_size); -- cgit v1.2.3 From 61c8304f246527563d8be7e85d47f5ffc24682ba Mon Sep 17 00:00:00 2001 From: aflpp Date: Mon, 15 Mar 2021 20:32:01 +0100 Subject: fixes --- src/afl-fuzz-queue.c | 2 +- src/afl-fuzz.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 835aba40..b2f88205 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -325,7 +325,7 @@ static u8 check_if_text(afl_state_t *afl, struct queue_entry *q) { if (len >= MAX_FILE) len = MAX_FILE - 1; if ((fd = open(q->fname, O_RDONLY)) < 0) return 0; - buf = afl_realloc(AFL_BUF_PARAM(in_scratch), len); + buf = afl_realloc(AFL_BUF_PARAM(in_scratch), len + 1); comp = read(fd, buf, len); close(fd); if (comp != (ssize_t)len) return 0; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index ff27048a..64e4b869 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1680,6 +1680,7 @@ int main(int argc, char **argv_orig, char **envp) { setenv("AFL_NO_AUTODICT", "1", 1); // loaded already afl->fsrv.trace_bits = afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode); + afl->cmplog_fsrv.trace_bits = afl->fsrv.trace_bits; afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, -- cgit v1.2.3 From d4fb7f8b4015297e1c74b28d671eba058cfb6366 Mon Sep 17 00:00:00 2001 From: realmadsci <71108352+realmadsci@users.noreply.github.com> Date: Fri, 12 Mar 2021 15:53:42 -0500 Subject: Add AFL_QEMU_CUSTOM_BIN environment flag In QEMU mode (-Q), setting AFL_QEMU_CUSTOM_BIN cause afl-fuzz to skip prepending afl-qemu-trace to your command line. Use this if you wish to use a custom afl-qemu-trace or if you need to modify the afl-qemu-trace arguments. --- src/afl-common.c | 7 +++++++ src/afl-fuzz-init.c | 1 + 2 files changed, 8 insertions(+) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 9f6eb564..58fbf765 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -149,6 +149,13 @@ void argv_cpy_free(char **argv) { char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { + if (unlikely(getenv("AFL_QEMU_CUSTOM_BIN"))) { + WARNF( + "AFL_QEMU_CUSTOM_BIN is enabled. " + "You must run your target under afl-qemu-trace on your own!"); + return argv; + } + if (!unlikely(own_loc)) { FATAL("BUG: param own_loc is NULL"); } u8 *tmp, *cp = NULL, *rsl, *own_copy; diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index ca2f75f1..82c1799e 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2592,6 +2592,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { } if (afl->afl_env.afl_skip_bin_check || afl->use_wine || afl->unicorn_mode || + (afl->fsrv.qemu_mode && getenv("AFL_QEMU_CUSTOM_BIN")) || afl->non_instrumented_mode) { return; -- cgit v1.2.3 From 01ad7610beaf772063c9011daae5fa3a3232494c Mon Sep 17 00:00:00 2001 From: realmadsci <71108352+realmadsci@users.noreply.github.com> Date: Mon, 15 Mar 2021 11:45:58 -0400 Subject: Remove AFL_PRELOAD and AFL_USE_QASAN handlers These are now processed in afl-qemu-trace so that the "copy+paste" code that is in all of the other AFL tools can be removed. This also allows the AFL_USE_QASAN flag to work the same when used with tools like afl-fuzz as it does with afl-qemu-trace. This is important in situations where loading the QASAN library changes the address of your desired entrypoint, or for crash validation using the same environment that afl-fuzz was using. With this change, the same set of environment variables can be used in exactly the same way between afl-fuzz, afl-showmap, and afl-qemu-trace, and you will get exactly the same guest environment. --- src/afl-analyze.c | 58 +---------------------------------------------------- src/afl-common.c | 60 ------------------------------------------------------- src/afl-fuzz.c | 59 +----------------------------------------------------- src/afl-showmap.c | 58 +---------------------------------------------------- src/afl-tmin.c | 58 +---------------------------------------------------- 5 files changed, 4 insertions(+), 289 deletions(-) (limited to 'src') diff --git a/src/afl-analyze.c b/src/afl-analyze.c index d46ecb8d..86b0f7e9 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -822,38 +822,7 @@ static void set_up_environment(void) { if (qemu_mode) { - u8 *qemu_preload = getenv("QEMU_SET_ENV"); - u8 *afl_preload = getenv("AFL_PRELOAD"); - u8 *buf; - - s32 i, afl_preload_size = strlen(afl_preload); - for (i = 0; i < afl_preload_size; ++i) { - - if (afl_preload[i] == ',') { - - PFATAL( - "Comma (',') is not allowed in AFL_PRELOAD when -Q is " - "specified!"); - - } - - } - - if (qemu_preload) { - - buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s", - qemu_preload, afl_preload, afl_preload); - - } else { - - buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s", - afl_preload, afl_preload); - - } - - setenv("QEMU_SET_ENV", buf, 1); - - ck_free(buf); + /* afl-qemu-trace takes care of converting AFL_PRELOAD. */ } else { @@ -1079,31 +1048,6 @@ int main(int argc, char **argv_orig, char **envp) { if (optind == argc || !in_file) { usage(argv[0]); } - if (qemu_mode && getenv("AFL_USE_QASAN")) { - - u8 *preload = getenv("AFL_PRELOAD"); - u8 *libqasan = get_libqasan_path(argv_orig[0]); - - if (!preload) { - - setenv("AFL_PRELOAD", libqasan, 0); - - } else { - - u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2); - strcpy(result, libqasan); - strcat(result, " "); - strcat(result, preload); - - setenv("AFL_PRELOAD", result, 1); - ck_free(result); - - } - - ck_free(libqasan); - - } - map_size = get_map_size(); use_hex_offsets = !!get_afl_env("AFL_ANALYZE_HEX"); diff --git a/src/afl-common.c b/src/afl-common.c index 9f6eb564..5ac50595 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -338,66 +338,6 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { } -/* Get libqasan path. */ - -u8 *get_libqasan_path(u8 *own_loc) { - - if (!unlikely(own_loc)) { FATAL("BUG: param own_loc is NULL"); } - - u8 *tmp, *cp = NULL, *rsl, *own_copy; - - tmp = getenv("AFL_PATH"); - - if (tmp) { - - cp = alloc_printf("%s/libqasan.so", tmp); - - if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); } - - return cp; - - } - - own_copy = ck_strdup(own_loc); - rsl = strrchr(own_copy, '/'); - - if (rsl) { - - *rsl = 0; - - cp = alloc_printf("%s/libqasan.so", own_copy); - ck_free(own_copy); - - if (!access(cp, X_OK)) { return cp; } - - } else { - - ck_free(own_copy); - - } - - if (!access(AFL_PATH "/libqasan.so", X_OK)) { - - if (cp) { ck_free(cp); } - - return ck_strdup(AFL_PATH "/libqasan.so"); - - } - - SAYF("\n" cLRD "[-] " cRST - "Oops, unable to find the 'libqasan.so' binary. The binary must be " - "built\n" - " separately by following the instructions in " - "qemu_mode/libqasan/README.md. " - "If you\n" - " already have the binary installed, you may need to specify " - "AFL_PATH in the\n" - " environment.\n"); - - FATAL("Failed to locate 'libqasan.so'."); - -} - /* Find binary, used by analyze, showmap, tmin @returns the path, allocating the string */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index ff27048a..3ca377f6 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1022,32 +1022,6 @@ int main(int argc, char **argv_orig, char **envp) { } - if (afl->fsrv.qemu_mode && getenv("AFL_USE_QASAN")) { - - u8 *preload = getenv("AFL_PRELOAD"); - u8 *libqasan = get_libqasan_path(argv_orig[0]); - - if (!preload) { - - setenv("AFL_PRELOAD", libqasan, 0); - - } else { - - u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2); - strcpy(result, libqasan); - strcat(result, " "); - strcat(result, preload); - - setenv("AFL_PRELOAD", result, 1); - ck_free(result); - - } - - afl->afl_env.afl_preload = (u8 *)getenv("AFL_PRELOAD"); - ck_free(libqasan); - - } - if (afl->fsrv.mem_limit && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260; OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" " @@ -1312,38 +1286,7 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->fsrv.qemu_mode) { - u8 *qemu_preload = getenv("QEMU_SET_ENV"); - u8 *afl_preload = getenv("AFL_PRELOAD"); - u8 *buf; - - s32 j, afl_preload_size = strlen(afl_preload); - for (j = 0; j < afl_preload_size; ++j) { - - if (afl_preload[j] == ',') { - - PFATAL( - "Comma (',') is not allowed in AFL_PRELOAD when -Q is " - "specified!"); - - } - - } - - if (qemu_preload) { - - buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s", - qemu_preload, afl_preload, afl_preload); - - } else { - - buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s", - afl_preload, afl_preload); - - } - - setenv("QEMU_SET_ENV", buf, 1); - - ck_free(buf); + /* afl-qemu-trace takes care of converting AFL_PRELOAD. */ } else { diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 0fc76193..7bf5a9c7 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -599,38 +599,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) { if (fsrv->qemu_mode) { - u8 *qemu_preload = getenv("QEMU_SET_ENV"); - u8 *afl_preload = getenv("AFL_PRELOAD"); - u8 *buf; - - s32 i, afl_preload_size = strlen(afl_preload); - for (i = 0; i < afl_preload_size; ++i) { - - if (afl_preload[i] == ',') { - - PFATAL( - "Comma (',') is not allowed in AFL_PRELOAD when -Q is " - "specified!"); - - } - - } - - if (qemu_preload) { - - buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s", - qemu_preload, afl_preload, afl_preload); - - } else { - - buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s", - afl_preload, afl_preload); - - } - - setenv("QEMU_SET_ENV", buf, 1); - - ck_free(buf); + /* afl-qemu-trace takes care of converting AFL_PRELOAD. */ } else { @@ -946,31 +915,6 @@ int main(int argc, char **argv_orig, char **envp) { if (optind == argc || !out_file) { usage(argv[0]); } - if (fsrv->qemu_mode && getenv("AFL_USE_QASAN")) { - - u8 *preload = getenv("AFL_PRELOAD"); - u8 *libqasan = get_libqasan_path(argv_orig[0]); - - if (!preload) { - - setenv("AFL_PRELOAD", libqasan, 0); - - } else { - - u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2); - strcpy(result, libqasan); - strcat(result, " "); - strcat(result, preload); - - setenv("AFL_PRELOAD", result, 1); - ck_free(result); - - } - - ck_free(libqasan); - - } - if (in_dir) { if (!out_file && !collect_coverage) diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 6d04c652..7ef8b9bf 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -753,38 +753,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) { if (fsrv->qemu_mode) { - u8 *qemu_preload = getenv("QEMU_SET_ENV"); - u8 *afl_preload = getenv("AFL_PRELOAD"); - u8 *buf; - - s32 i, afl_preload_size = strlen(afl_preload); - for (i = 0; i < afl_preload_size; ++i) { - - if (afl_preload[i] == ',') { - - PFATAL( - "Comma (',') is not allowed in AFL_PRELOAD when -Q is " - "specified!"); - - } - - } - - if (qemu_preload) { - - buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s", - qemu_preload, afl_preload, afl_preload); - - } else { - - buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s", - afl_preload, afl_preload); - - } - - setenv("QEMU_SET_ENV", buf, 1); - - ck_free(buf); + /* afl-qemu-trace takes care of converting AFL_PRELOAD. */ } else { @@ -1079,31 +1048,6 @@ int main(int argc, char **argv_orig, char **envp) { check_environment_vars(envp); setenv("AFL_NO_AUTODICT", "1", 1); - if (fsrv->qemu_mode && getenv("AFL_USE_QASAN")) { - - u8 *preload = getenv("AFL_PRELOAD"); - u8 *libqasan = get_libqasan_path(argv_orig[0]); - - if (!preload) { - - setenv("AFL_PRELOAD", libqasan, 0); - - } else { - - u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2); - strcpy(result, libqasan); - strcat(result, " "); - strcat(result, preload); - - setenv("AFL_PRELOAD", result, 1); - ck_free(result); - - } - - ck_free(libqasan); - - } - /* initialize cmplog_mode */ shm.cmplog_mode = 0; -- cgit v1.2.3 From 862cb3217f5983e5cfff6568f6b31fcf1e960802 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 16 Mar 2021 14:38:13 +0100 Subject: fix cmplog rtn --- src/afl-common.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index bfb05a67..27b63434 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -150,10 +150,12 @@ void argv_cpy_free(char **argv) { char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) { if (unlikely(getenv("AFL_QEMU_CUSTOM_BIN"))) { + WARNF( - "AFL_QEMU_CUSTOM_BIN is enabled. " - "You must run your target under afl-qemu-trace on your own!"); + "AFL_QEMU_CUSTOM_BIN is enabled. " + "You must run your target under afl-qemu-trace on your own!"); return argv; + } if (!unlikely(own_loc)) { FATAL("BUG: param own_loc is NULL"); } -- cgit v1.2.3 From 7c2436c7114e21f029b06346421a73910deac578 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 16 Mar 2021 19:34:34 +0100 Subject: no runtime for shared linking --- src/afl-cc.c | 59 +++++++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 44654de0..18401d0d 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -959,56 +959,59 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (compiler_mode != GCC && compiler_mode != CLANG) { - switch (bit_mode) { + if (!shared_linking) { - case 0: - cc_params[cc_par_cnt++] = - alloc_printf("%s/afl-compiler-rt.o", obj_path); - if (lto_mode) - cc_params[cc_par_cnt++] = - alloc_printf("%s/afl-llvm-rt-lto.o", obj_path); - break; + switch (bit_mode) { - case 32: - cc_params[cc_par_cnt++] = - alloc_printf("%s/afl-compiler-rt-32.o", obj_path); - if (access(cc_params[cc_par_cnt - 1], R_OK)) - FATAL("-m32 is not supported by your compiler"); - if (lto_mode) { + case 0: + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-compiler-rt.o", obj_path); + if (lto_mode) + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-rt-lto.o", obj_path); + break; + case 32: cc_params[cc_par_cnt++] = - alloc_printf("%s/afl-llvm-rt-lto-32.o", obj_path); + alloc_printf("%s/afl-compiler-rt-32.o", obj_path); if (access(cc_params[cc_par_cnt - 1], R_OK)) FATAL("-m32 is not supported by your compiler"); + if (lto_mode) { - } + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-rt-lto-32.o", obj_path); + if (access(cc_params[cc_par_cnt - 1], R_OK)) + FATAL("-m32 is not supported by your compiler"); - break; + } - case 64: - cc_params[cc_par_cnt++] = - alloc_printf("%s/afl-compiler-rt-64.o", obj_path); - if (access(cc_params[cc_par_cnt - 1], R_OK)) - FATAL("-m64 is not supported by your compiler"); - if (lto_mode) { + break; + case 64: cc_params[cc_par_cnt++] = - alloc_printf("%s/afl-llvm-rt-lto-64.o", obj_path); + alloc_printf("%s/afl-compiler-rt-64.o", obj_path); if (access(cc_params[cc_par_cnt - 1], R_OK)) FATAL("-m64 is not supported by your compiler"); + if (lto_mode) { - } + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-rt-lto-64.o", obj_path); + if (access(cc_params[cc_par_cnt - 1], R_OK)) + FATAL("-m64 is not supported by your compiler"); - break; + } - } + break; + + } #if !defined(__APPLE__) && !defined(__sun) - if (!shared_linking) cc_params[cc_par_cnt++] = alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); #endif + } + #if defined(USEMMAP) && !defined(__HAIKU__) cc_params[cc_par_cnt++] = "-lrt"; #endif -- cgit v1.2.3 From f59ef29c267c8500cc07115b10355c82dd770064 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 17 Mar 2021 01:08:10 +0100 Subject: fix attempt --- src/afl-fuzz.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index cfb507a7..12642557 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1539,9 +1539,9 @@ int main(int argc, char **argv_orig, char **envp) { &afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); // only reinitialize when it makes sense - if ((map_size < new_map_size || + if ((map_size < new_map_size /*|| (new_map_size != MAP_SIZE && new_map_size < map_size && - map_size - new_map_size > MAP_SIZE))) { + map_size - new_map_size > MAP_SIZE)*/)) { OKF("Re-initializing maps to %u bytes", new_map_size); @@ -1570,8 +1570,6 @@ int main(int argc, char **argv_orig, char **envp) { } - afl->fsrv.map_size = map_size; - } if (afl->cmplog_binary) { @@ -1629,16 +1627,14 @@ int main(int argc, char **argv_orig, char **envp) { afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child); - } else { - - afl->cmplog_fsrv.map_size = new_map_size; - } OKF("Cmplog forkserver successfully started"); } + fprintf(stderr, "NORMAL %u, CMPLOG %u\n", afl->fsrv.map_size, afl->cmplog_fsrv.map_size); + load_auto(afl); if (extras_dir_cnt) { -- cgit v1.2.3 From 413807db01b642a2ad4c70e94517d74c11ace91c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 17 Mar 2021 01:25:21 +0100 Subject: lto test --- src/afl-cc.c | 6 ++++-- src/afl-fuzz.c | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 18401d0d..4a724c12 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -959,11 +959,10 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (compiler_mode != GCC && compiler_mode != CLANG) { - if (!shared_linking) { - switch (bit_mode) { case 0: + if (!shared_linking) cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt.o", obj_path); if (lto_mode) @@ -972,6 +971,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { break; case 32: + if (!shared_linking) cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt-32.o", obj_path); if (access(cc_params[cc_par_cnt - 1], R_OK)) @@ -988,6 +988,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { break; case 64: + if (!shared_linking) cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt-64.o", obj_path); if (access(cc_params[cc_par_cnt - 1], R_OK)) @@ -1006,6 +1007,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } #if !defined(__APPLE__) && !defined(__sun) + if (!shared_linking) cc_params[cc_par_cnt++] = alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); #endif diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 12642557..6c170632 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1633,6 +1633,7 @@ int main(int argc, char **argv_orig, char **envp) { } + printf("NORMAL %u, CMPLOG %u\n", afl->fsrv.map_size, afl->cmplog_fsrv.map_size); fprintf(stderr, "NORMAL %u, CMPLOG %u\n", afl->fsrv.map_size, afl->cmplog_fsrv.map_size); load_auto(afl); -- cgit v1.2.3 From c6f1c56c15801662eef7b0b19e42287ddb3b97a7 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 17 Mar 2021 01:27:01 +0100 Subject: fix --- src/afl-cc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 4a724c12..206066fd 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1018,8 +1018,6 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = "-lrt"; #endif - } - #endif cc_params[cc_par_cnt] = NULL; -- cgit v1.2.3 From dda4757b358d1d28d5e48028ea22023c3977d706 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 17 Mar 2021 01:40:27 +0100 Subject: debug --- src/afl-fuzz.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 6c170632..2fde561c 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1633,8 +1633,10 @@ int main(int argc, char **argv_orig, char **envp) { } + if (afl->debug) { printf("NORMAL %u, CMPLOG %u\n", afl->fsrv.map_size, afl->cmplog_fsrv.map_size); fprintf(stderr, "NORMAL %u, CMPLOG %u\n", afl->fsrv.map_size, afl->cmplog_fsrv.map_size); + } load_auto(afl); -- cgit v1.2.3 From 5e2a5f1110e29c36f1c41fb4677ab698c5d571c0 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 17 Mar 2021 10:26:02 +0100 Subject: shmem map size in config.h --- src/afl-cc.c | 62 ++++++++++++++++++++++++++++---------------------------- src/afl-common.c | 2 +- src/afl-fuzz.c | 24 ++++++++++++++-------- 3 files changed, 48 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 206066fd..ebbd390c 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -959,63 +959,63 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (compiler_mode != GCC && compiler_mode != CLANG) { - switch (bit_mode) { + switch (bit_mode) { - case 0: - if (!shared_linking) + case 0: + if (!shared_linking) cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt.o", obj_path); - if (lto_mode) - cc_params[cc_par_cnt++] = - alloc_printf("%s/afl-llvm-rt-lto.o", obj_path); - break; + if (lto_mode) + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-rt-lto.o", obj_path); + break; - case 32: - if (!shared_linking) + case 32: + if (!shared_linking) cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt-32.o", obj_path); + if (access(cc_params[cc_par_cnt - 1], R_OK)) + FATAL("-m32 is not supported by your compiler"); + if (lto_mode) { + + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-rt-lto-32.o", obj_path); if (access(cc_params[cc_par_cnt - 1], R_OK)) FATAL("-m32 is not supported by your compiler"); - if (lto_mode) { - - cc_params[cc_par_cnt++] = - alloc_printf("%s/afl-llvm-rt-lto-32.o", obj_path); - if (access(cc_params[cc_par_cnt - 1], R_OK)) - FATAL("-m32 is not supported by your compiler"); - } + } - break; + break; - case 64: - if (!shared_linking) + case 64: + if (!shared_linking) cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt-64.o", obj_path); + if (access(cc_params[cc_par_cnt - 1], R_OK)) + FATAL("-m64 is not supported by your compiler"); + if (lto_mode) { + + cc_params[cc_par_cnt++] = + alloc_printf("%s/afl-llvm-rt-lto-64.o", obj_path); if (access(cc_params[cc_par_cnt - 1], R_OK)) FATAL("-m64 is not supported by your compiler"); - if (lto_mode) { - cc_params[cc_par_cnt++] = - alloc_printf("%s/afl-llvm-rt-lto-64.o", obj_path); - if (access(cc_params[cc_par_cnt - 1], R_OK)) - FATAL("-m64 is not supported by your compiler"); - - } + } - break; + break; - } + } #if !defined(__APPLE__) && !defined(__sun) - if (!shared_linking) + if (!shared_linking) cc_params[cc_par_cnt++] = alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); #endif - } + } #if defined(USEMMAP) && !defined(__HAIKU__) - cc_params[cc_par_cnt++] = "-lrt"; + cc_params[cc_par_cnt++] = "-lrt"; #endif #endif diff --git a/src/afl-common.c b/src/afl-common.c index 27b63434..7e56ce3f 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -1072,7 +1072,7 @@ u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) { /* Reads the map size from ENV */ u32 get_map_size(void) { - uint32_t map_size = 8000000; // a very large default map + uint32_t map_size = DEFAULT_SHMEM_SIZE; char * ptr; if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 2fde561c..8318a92e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1527,11 +1527,13 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->non_instrumented_mode && !afl->fsrv.qemu_mode && !afl->unicorn_mode) { - if (map_size <= 8000000 && !afl->non_instrumented_mode && + if (map_size <= DEFAULT_SHMEM_SIZE && !afl->non_instrumented_mode && !afl->fsrv.qemu_mode && !afl->unicorn_mode) { - afl->fsrv.map_size = 8000000; // dummy temporary value - setenv("AFL_MAP_SIZE", "8000000", 1); + afl->fsrv.map_size = DEFAULT_SHMEM_SIZE; // dummy temporary value + char vbuf[16]; + snprintf(vbuf, sizeof(vbuf), "%u", DEFAULT_SHMEM_SIZE); + setenv("AFL_MAP_SIZE", vbuf, 1); } @@ -1582,11 +1584,13 @@ int main(int argc, char **argv_orig, char **envp) { afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary; afl->cmplog_fsrv.init_child_func = cmplog_exec_child; - if (map_size <= 8000000 && !afl->non_instrumented_mode && + if (map_size <= DEFAULT_SHMEM_SIZE && !afl->non_instrumented_mode && !afl->fsrv.qemu_mode && !afl->unicorn_mode) { - afl->cmplog_fsrv.map_size = 8000000; // dummy temporary value - setenv("AFL_MAP_SIZE", "8000000", 1); + afl->fsrv.map_size = DEFAULT_SHMEM_SIZE; // dummy temporary value + char vbuf[16]; + snprintf(vbuf, sizeof(vbuf), "%u", DEFAULT_SHMEM_SIZE); + setenv("AFL_MAP_SIZE", vbuf, 1); } @@ -1634,8 +1638,12 @@ int main(int argc, char **argv_orig, char **envp) { } if (afl->debug) { - printf("NORMAL %u, CMPLOG %u\n", afl->fsrv.map_size, afl->cmplog_fsrv.map_size); - fprintf(stderr, "NORMAL %u, CMPLOG %u\n", afl->fsrv.map_size, afl->cmplog_fsrv.map_size); + + printf("NORMAL %u, CMPLOG %u\n", afl->fsrv.map_size, + afl->cmplog_fsrv.map_size); + fprintf(stderr, "NORMAL %u, CMPLOG %u\n", afl->fsrv.map_size, + afl->cmplog_fsrv.map_size); + } load_auto(afl); -- cgit v1.2.3 From cdd30c766b7102dcd5413efd8f009b4388b40425 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 17 Mar 2021 11:25:14 +0100 Subject: fix m32/m64 --- src/afl-cc.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index ebbd390c..c4f8f3fc 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -971,11 +971,15 @@ static void edit_params(u32 argc, char **argv, char **envp) { break; case 32: - if (!shared_linking) + if (!shared_linking) { + cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt-32.o", obj_path); - if (access(cc_params[cc_par_cnt - 1], R_OK)) - FATAL("-m32 is not supported by your compiler"); + if (access(cc_params[cc_par_cnt - 1], R_OK)) + FATAL("-m32 is not supported by your compiler"); + + } + if (lto_mode) { cc_params[cc_par_cnt++] = @@ -988,11 +992,15 @@ static void edit_params(u32 argc, char **argv, char **envp) { break; case 64: - if (!shared_linking) + if (!shared_linking) { + cc_params[cc_par_cnt++] = alloc_printf("%s/afl-compiler-rt-64.o", obj_path); - if (access(cc_params[cc_par_cnt - 1], R_OK)) - FATAL("-m64 is not supported by your compiler"); + if (access(cc_params[cc_par_cnt - 1], R_OK)) + FATAL("-m64 is not supported by your compiler"); + + } + if (lto_mode) { cc_params[cc_par_cnt++] = -- cgit v1.2.3 From 513bd703845283c4f94ae2760c48ca8cc38a0076 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 17 Mar 2021 12:44:07 +0100 Subject: shared linking fix --- src/afl-cc.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index c4f8f3fc..e13f285d 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -682,17 +682,42 @@ static void edit_params(u32 argc, char **argv, char **envp) { /* Detect stray -v calls from ./configure scripts. */ + u8 skip_next = 0; while (--argc) { u8 *cur = *(++argv); + if (skip_next) { + + skip_next = 0; + continue; + + } + if (!strncmp(cur, "--afl", 5)) continue; if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue; if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue; if (!strncmp(cur, "-fno-unroll", 11)) continue; if (strstr(cur, "afl-compiler-rt") || strstr(cur, "afl-llvm-rt")) continue; - if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined")) + if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined") || + !strcmp(cur, "--no-undefined")) { + continue; + + } + + if (!strcmp(cur, "-z")) { + + u8 *param = *(argv + 1); + if (!strcmp(param, "defs")) { + + skip_next = 1; + continue; + + } + + } + if (!strncmp(cur, "-fsanitize=fuzzer-", strlen("-fsanitize=fuzzer-")) || !strncmp(cur, "-fsanitize-coverage", strlen("-fsanitize-coverage"))) { @@ -1015,7 +1040,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } #if !defined(__APPLE__) && !defined(__sun) - if (!shared_linking) + if (shared_linking) cc_params[cc_par_cnt++] = alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); #endif -- cgit v1.2.3 From 94312796f936ba1830b61432a0f958e192dd212f Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 17 Mar 2021 13:16:02 +0100 Subject: better map variability --- src/afl-fuzz.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 8318a92e..ff4c5281 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1584,12 +1584,14 @@ int main(int argc, char **argv_orig, char **envp) { afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary; afl->cmplog_fsrv.init_child_func = cmplog_exec_child; - if (map_size <= DEFAULT_SHMEM_SIZE && !afl->non_instrumented_mode && - !afl->fsrv.qemu_mode && !afl->unicorn_mode) { + if ((map_size <= DEFAULT_SHMEM_SIZE || + afl->cmplog_fsrv.map_size < map_size) && + !afl->non_instrumented_mode && !afl->fsrv.qemu_mode && + !afl->unicorn_mode) { - afl->fsrv.map_size = DEFAULT_SHMEM_SIZE; // dummy temporary value + afl->cmplog_fsrv.map_size = MAX(map_size, (u32)DEFAULT_SHMEM_SIZE); char vbuf[16]; - snprintf(vbuf, sizeof(vbuf), "%u", DEFAULT_SHMEM_SIZE); + snprintf(vbuf, sizeof(vbuf), "%u", afl->cmplog_fsrv.map_size); setenv("AFL_MAP_SIZE", vbuf, 1); } -- cgit v1.2.3