From 55b67f1372b399b0b2ebd3e7aad7b7e130b2d00b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 26 Sep 2024 14:42:59 +0200 Subject: fix postprocess for calibration --- docs/Changelog.md | 1 + src/afl-fuzz-run.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 7043202f..68d362db 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -15,6 +15,7 @@ function after the target has been restarted. - because of bad math and undefined behaviour fixes we have to change the CMPLOG map. **YOU NEED TO RECOMPILE CMPLOG TARGETS** + - fixed custom_post_process for calibration - frida_mode: - AFL_FRIDA_PERSISTENT_ADDR can now be be any reachable address not just a function entry diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 4ce17eb2..c2e29fb3 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -487,6 +487,9 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, } + u8 saved_afl_post_process_keep_original = + afl->afl_env.afl_post_process_keep_original; + /* we need a dummy run if this is LTO + cmplog */ if (unlikely(afl->shm.cmplog_mode)) { @@ -661,6 +664,9 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, abort_calibration: + afl->afl_env.afl_post_process_keep_original = + saved_afl_post_process_keep_original; + if (new_bits == 2 && !q->has_new_cov) { q->has_new_cov = 1; -- cgit 1.4.1 From 12271064f8570213ea4169a2ae94f68304d5a73d Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 27 Sep 2024 09:20:08 +0200 Subject: fix fix --- src/afl-fuzz-run.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index c2e29fb3..a3787e5c 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -489,6 +489,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, u8 saved_afl_post_process_keep_original = afl->afl_env.afl_post_process_keep_original; + afl->afl_env.afl_post_process_keep_original = 1; /* we need a dummy run if this is LTO + cmplog */ if (unlikely(afl->shm.cmplog_mode)) { -- cgit 1.4.1 From b88f132975b41aa16c43ee5e2bc3a243b79330ec Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 29 Sep 2024 17:11:07 +0200 Subject: llvm20 fix --- docs/Changelog.md | 1 + instrumentation/SanitizerCoverageLTO.so.cc | 6 +++++- instrumentation/SanitizerCoveragePCGUARD.so.cc | 11 ++++++++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index 68d362db..3800a718 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -29,6 +29,7 @@ - custom mutators: - custom_send_tcp custom mutator added, thanks to @dergoegge - afl-cc + - fix to support pointless changes in LLVM 20 - new runtime (!) variable: `AFL_OLD_FORKSERVER` to use the old vanilla AFL type forkserver. Useful for symcc/symqemu/nautilus/etc. with AFL_LLVM_INSTRUMENT=CLASSIC diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 63ea71c1..6ec84dcd 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -50,7 +50,11 @@ #include "llvm/Support/SpecialCaseList.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Transforms/Instrumentation.h" +#if LLVM_VERSION_MAJOR < 20 + #include "llvm/Transforms/Instrumentation.h" +#else + #include "llvm/Transforms/Utils/Instrumentation.h" +#endif #if LLVM_VERSION_MAJOR < 17 #include "llvm/Transforms/IPO/PassManagerBuilder.h" #endif diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index 49fe904b..859b4e7b 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -63,11 +63,16 @@ #if LLVM_VERSION_MAJOR < 15 #include "llvm/Support/raw_ostream.h" #endif -#if LLVM_VERSION_MAJOR < 17 - #include "llvm/Transforms/Instrumentation.h" +#if LLVM_VERSION_MAJOR < 20 + #if LLVM_VERSION_MAJOR < 17 + #include "llvm/Transforms/Instrumentation.h" + #else + #include "llvm/TargetParser/Triple.h" + #endif #else - #include "llvm/TargetParser/Triple.h" + #include "llvm/Transforms/Utils/Instrumentation.h" #endif + #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/ModuleUtils.h" -- cgit 1.4.1 From 146e535f7b644a3d38f8e90c415974b23ff295c0 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 1 Oct 2024 10:13:35 +0200 Subject: persistent record for frida and qmeu --- src/afl-forkserver.c | 7 +++++-- src/afl-fuzz-init.c | 16 ++++++++++++---- src/afl-fuzz-stats.c | 8 ++++++-- src/afl-fuzz.c | 28 +++++++++++++++++----------- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index ae3c7ccc..51299009 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -536,12 +536,15 @@ static void report_error_and_exit(int error) { #ifdef __linux__ void nyx_load_target_hash(afl_forkserver_t *fsrv) { + void *nyx_config = fsrv->nyx_handlers->nyx_config_load(fsrv->target_path); - fsrv->nyx_target_hash64 = fsrv->nyx_handlers->nyx_get_target_hash64(nyx_config); + fsrv->nyx_target_hash64 = + fsrv->nyx_handlers->nyx_get_target_hash64(nyx_config); fsrv->nyx_handlers->nyx_config_free(nyx_config); + } -#endif +#endif /* Spins up fork server. The idea is explained here: diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 9eaa661d..a9397232 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1237,19 +1237,26 @@ void perform_dry_run(afl_state_t *afl) { u8 crash_log_fn[PATH_MAX]; snprintf(crash_log_fn, PATH_MAX, "%s.log", crash_fn); - fd = open(crash_log_fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION); - if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", crash_log_fn); } + fd = open(crash_log_fn, O_WRONLY | O_CREAT | O_EXCL, + DEFAULT_PERMISSION); + if (unlikely(fd < 0)) { + + PFATAL("Unable to create '%s'", crash_log_fn); + + } u32 nyx_aux_string_len = afl->fsrv.nyx_handlers->nyx_get_aux_string( afl->fsrv.nyx_runner, afl->fsrv.nyx_aux_string, afl->fsrv.nyx_aux_string_len); - ck_write(fd, afl->fsrv.nyx_aux_string, nyx_aux_string_len, crash_log_fn); + ck_write(fd, afl->fsrv.nyx_aux_string, nyx_aux_string_len, + crash_log_fn); close(fd); } + #endif - + afl->last_crash_time = get_cur_time(); afl->last_crash_execs = afl->fsrv.total_execs; @@ -2905,6 +2912,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { afl->fsrv.target_path); } + #endif if (stat(afl->fsrv.target_path, &st) || !S_ISREG(st.st_mode) || diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index b1a84cb6..a7465330 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -83,12 +83,16 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { #ifdef __linux__ if (afl->fsrv.nyx_mode) { + nyx_load_target_hash(&afl->fsrv); fprintf(f2, "%llx\n", afl->fsrv.nyx_target_hash64); - } - else { + + } else { + fprintf(f2, "%p\n", (void *)get_binary_hash(afl->fsrv.target_path)); + } + #else fprintf(f2, "%p\n", (void *)get_binary_hash(afl->fsrv.target_path)); #endif diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index a2fd4b76..7a940031 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1505,7 +1505,8 @@ int main(int argc, char **argv_orig, char **envp) { #ifdef __linux__ if (afl->fsrv.nyx_mode) { - OKF("AFL++ Nyx mode is enabled (developed and maintained by Sergej Schumilo)"); + OKF("AFL++ Nyx mode is enabled (developed and maintained by Sergej " + "Schumilo)"); OKF("Nyx is open source, get it at https://github.com/Nyx-Fuzz"); } @@ -2225,23 +2226,27 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->in_place_resume && !afl->afl_env.afl_no_fastresume) { -#ifdef __linux__ + #ifdef __linux__ u64 target_hash = 0; if (afl->fsrv.nyx_mode) { + nyx_load_target_hash(&afl->fsrv); target_hash = afl->fsrv.nyx_target_hash64; - } - else { + + } else { + target_hash = get_binary_hash(afl->fsrv.target_path); + } -#else + + #else u64 target_hash = get_binary_hash(afl->fsrv.target_path); -#endif + #endif if ((!target_hash || prev_target_hash != target_hash) -#ifdef __linux__ - || (afl->fsrv.nyx_mode && target_hash == 0) -#endif + #ifdef __linux__ + || (afl->fsrv.nyx_mode && target_hash == 0) + #endif ) { ACTF("Target binary is different, cannot perform FAST RESUME!"); @@ -2386,10 +2391,11 @@ int main(int argc, char **argv_orig, char **envp) { #ifdef AFL_PERSISTENT_RECORD if (unlikely(afl->fsrv.persistent_record)) { - if (!getenv(PERSIST_ENV_VAR)) { + if (!getenv(PERSIST_ENV_VAR) && !getenv("AFL_FRIDA_PERSISTENT_ADDR") && + !getenv("AFL_QEMU_PERSISTENT_ADDR")) { FATAL( - "Target binary is not compiled in persistent mode, " + "Target binary is not compiled/run in persistent mode, " "AFL_PERSISTENT_RECORD makes no sense."); } -- cgit 1.4.1 From cb5a61d8a1caf235a4852559086895ce841ac292 Mon Sep 17 00:00:00 2001 From: Carlo Cabrera <30379873+carlocab@users.noreply.github.com> Date: Wed, 2 Oct 2024 17:56:43 +0800 Subject: Update macOS linker flags in GNUmakefile.llvm `-flat_namespace` is effectively deprecated and doesn't really work as expected these days. Omitting the `-flat_namespace` means that binaries are built with a two-level namespace, which don't support `-undefined suppress`. The idiomatic way of telling the linker to look up undefined symbols at runtime is using `-undefined dynamic_lookup`, which is supported by a two-level namespace. See also: ocaml/ocaml#10723 mono/mono#21257 --- GNUmakefile.llvm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm index d5dcb09b..2e806ab8 100644 --- a/GNUmakefile.llvm +++ b/GNUmakefile.llvm @@ -327,7 +327,7 @@ endif # User teor2345 reports that this is required to make things work on MacOS X. ifeq "$(SYS)" "Darwin" - CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress + CLANG_LFL += -Wl,-undefined,dynamic_lookup override LLVM_HAVE_LTO := 0 override LLVM_LTO := 0 else -- cgit 1.4.1 From 994ac558787cc10512854b85115e7f5e5e268513 Mon Sep 17 00:00:00 2001 From: ea Date: Wed, 2 Oct 2024 13:08:24 -0500 Subject: Fix uninitialized alloc_canary in libdislocator When random alloc_canary env var option was introduced, a possibility for use of uninitialized alloc_canary value was made. In most cases, constructor will be called during shared library load and the alloc_canary would be initialized to either its default value or a randomly generated one if forced by AFL_RANDOM_ALLOC_CANARY env var. However, in some cases, libraries loaded before libdislocator will make allocations (still using libdislocator's allocation functions) while alloc_canary is still uninitialized. In such cases, canary value is usually NULL. If such allocated value is then free()'d after libdislocator's constructor has been run, call to free() will fail causing a false positive. This condition usually happens while calling library destructors at process termination. The patch ensures the canary value is initialized in all cases, and introduces a destructor that reverts it to default value. This does mean that certain number of early allocations will use the default canary value rather than the random one set afterwards. This seems like a reasonable tradeoff as I haven't found a surefire way of forcing libdislocator's constructor to run first in all possible cases (if nothing else, libphtread usually has priority). --- utils/libdislocator/libdislocator.so.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/utils/libdislocator/libdislocator.so.c b/utils/libdislocator/libdislocator.so.c index b80be1a1..f41491b1 100644 --- a/utils/libdislocator/libdislocator.so.c +++ b/utils/libdislocator/libdislocator.so.c @@ -162,7 +162,7 @@ static u8 alloc_verbose, /* Additional debug messages */ static _Atomic size_t total_mem; /* Currently allocated mem */ static __thread u32 call_depth; /* To avoid recursion via fprintf() */ -static u32 alloc_canary; +static u32 alloc_canary = ALLOC_CANARY; /* This is the main alloc function. It allocates one page more than necessary, sets that tailing page to PROT_NONE, and then increments the return address @@ -578,6 +578,13 @@ __attribute__((constructor)) void __dislocator_init(void) { } +__attribute__((destructor)) void __dislocator_fini(void) { + + alloc_canary = ALLOC_CANARY; // restore to default canary value + +} + + /* NetBSD fault handler specific api subset */ void (*esetfunc(void (*fn)(int, const char *, ...)))(int, const char *, ...) { -- cgit 1.4.1 From d6a2edb42a680b999256d5b78082975713973db7 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 7 Oct 2024 10:11:10 +0200 Subject: update nyx --- docs/Changelog.md | 2 ++ nyx_mode/LIBNYX_VERSION | 2 +- nyx_mode/QEMU-Nyx | 2 +- nyx_mode/QEMU_NYX_VERSION | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index 3800a718..5b809d61 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -26,6 +26,8 @@ @CowBoy4mH3LL - unicorn_mode: - fix install and forkserver (thanks aarnav!) + - nyx_mode: + - bugfixes - custom mutators: - custom_send_tcp custom mutator added, thanks to @dergoegge - afl-cc diff --git a/nyx_mode/LIBNYX_VERSION b/nyx_mode/LIBNYX_VERSION index 5f7c9a5b..fdd1b46b 100644 --- a/nyx_mode/LIBNYX_VERSION +++ b/nyx_mode/LIBNYX_VERSION @@ -1 +1 @@ -ea6ceb9 \ No newline at end of file +ea6ceb9 diff --git a/nyx_mode/QEMU-Nyx b/nyx_mode/QEMU-Nyx index e5e1c4c2..ff1c8973 160000 --- a/nyx_mode/QEMU-Nyx +++ b/nyx_mode/QEMU-Nyx @@ -1 +1 @@ -Subproject commit e5e1c4c21ff9c4dc80e6409d4eab47146c6024cd +Subproject commit ff1c89732115274e912a2809fcba58e67df23dfd diff --git a/nyx_mode/QEMU_NYX_VERSION b/nyx_mode/QEMU_NYX_VERSION index c6ed0c6a..4543932d 100644 --- a/nyx_mode/QEMU_NYX_VERSION +++ b/nyx_mode/QEMU_NYX_VERSION @@ -1 +1 @@ -e5e1c4c21ff9c4dc80e6409d4eab47146c6024cd +ff1c897321 -- cgit 1.4.1