aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2023-04-12 10:54:08 +0200
committerGitHub <noreply@github.com>2023-04-12 10:54:08 +0200
commit4f2d9eeaaa6b702ef28eb883f9000321eaf1fe9b (patch)
tree125cecc79c148552844723e95ddd246bf918d6fc
parent7101192865893e00b9029d0cb898a3ca3015d50b (diff)
parent743ae507756db0707a213cd8272b219b0de0f514 (diff)
downloadafl++-4f2d9eeaaa6b702ef28eb883f9000321eaf1fe9b.tar.gz
Merge pull request #1700 from AFLplusplus/dev
push to stable
-rwxr-xr-x.custom-format.py2
-rw-r--r--Dockerfile4
-rw-r--r--GNUmakefile2
-rwxr-xr-xafl-whatsup13
-rw-r--r--docs/Changelog.md6
-rw-r--r--docs/afl-fuzz_approach.md1
-rw-r--r--docs/env_variables.md2
-rw-r--r--include/afl-fuzz.h10
-rw-r--r--instrumentation/SanitizerCoverageLTO.so.cc6
-rw-r--r--instrumentation/afl-compiler-rt.o.c11
-rw-r--r--instrumentation/afl-llvm-common.cc1
-rw-r--r--src/afl-as.c22
-rw-r--r--src/afl-cc.c102
-rw-r--r--src/afl-fuzz-bitmap.c10
-rw-r--r--src/afl-fuzz-mutators.c16
-rw-r--r--src/afl-fuzz-one.c9
-rw-r--r--src/afl-fuzz-python.c13
-rw-r--r--src/afl-fuzz-queue.c42
-rw-r--r--src/afl-fuzz-state.c10
-rw-r--r--src/afl-fuzz-stats.c52
-rw-r--r--src/afl-fuzz.c31
-rwxr-xr-xtest/test-basic.sh2
-rw-r--r--utils/aflpp_driver/aflpp_driver.c41
23 files changed, 275 insertions, 133 deletions
diff --git a/.custom-format.py b/.custom-format.py
index d07c26df..1295ce55 100755
--- a/.custom-format.py
+++ b/.custom-format.py
@@ -40,7 +40,7 @@ def check_clang_format_pip_version():
if importlib.util.find_spec('clang_format'):
# Check if the installed version is the expected LLVM version
if importlib.metadata.version('clang-format')\
- .startswith(CURRENT_LLVM+'.'):
+ .startswith(str(CURRENT_LLVM)+'.'):
return True
else:
# Return False, because the clang-format version does not match
diff --git a/Dockerfile b/Dockerfile
index 59ce8778..4e53de40 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -67,6 +67,8 @@ RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCC_VERSION} 0
RUN wget -qO- https://sh.rustup.rs | CARGO_HOME=/etc/cargo sh -s -- -y -q --no-modify-path
ENV PATH=$PATH:/etc/cargo/bin
+RUN apt clean -y
+
ENV LLVM_CONFIG=llvm-config-${LLVM_VERSION}
ENV AFL_SKIP_CPUFREQ=1
ENV AFL_TRY_AFFINITY=1
@@ -92,4 +94,4 @@ RUN sed -i.bak 's/^ -/ /g' GNUmakefile && \
RUN echo "set encoding=utf-8" > /root/.vimrc && \
echo ". /etc/bash_completion" >> ~/.bashrc && \
echo 'alias joe="joe --wordwrap --joe_state -nobackup"' >> ~/.bashrc && \
- echo "export PS1='"'[afl++ \h] \w$(__git_ps1) \$ '"'" >> ~/.bashrc
+ echo "export PS1='"'[afl++ \h] \w \$ '"'" >> ~/.bashrc
diff --git a/GNUmakefile b/GNUmakefile
index 72da14ea..208e965b 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -196,7 +196,7 @@ ifeq "$(PYTHON_INCLUDE)" ""
ifneq "$(shell command -v python3-config 2>/dev/null)" ""
PYTHON_INCLUDE ?= $(shell python3-config --includes)
PYTHON_VERSION ?= $(strip $(shell python3 --version 2>&1))
- # Starting with python3.8, we need to pass the `embed` flag. Earier versions didn't know this flag.
+ # Starting with python3.8, we need to pass the `embed` flag. Earlier versions didn't know this flag.
ifeq "$(shell python3-config --embed --libs 2>/dev/null | grep -q lpython && echo 1 )" "1"
PYTHON_LIB ?= $(shell python3-config --libs --embed --ldflags)
else
diff --git a/afl-whatsup b/afl-whatsup
index 5546523a..cec1ae28 100755
--- a/afl-whatsup
+++ b/afl-whatsup
@@ -70,10 +70,10 @@ if [ -d queue ]; then
fi
-RED=`tput setaf 9 1 1`
-GREEN=`tput setaf 2 1 1`
-BLUE=`tput setaf 4 1 1`
-YELLOW=`tput setaf 11 1 1`
+RED=`tput setaf 9 1 1 2>/dev/null`
+GREEN=`tput setaf 2 1 1 2>/dev/null`
+BLUE=`tput setaf 4 1 1 2>/dev/null`
+YELLOW=`tput setaf 11 1 1 2>/dev/null`
NC=`tput sgr0`
RESET="$NC"
@@ -141,7 +141,8 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
sed 's/^command_line.*$/_skip:1/;s/[ ]*:[ ]*/="/;s/$/"/' "$i" >"$TMP"
. "$TMP"
-
+ DIR=$(dirname "$i")
+ DIR=${DIR##*/}
RUN_UNIX=$run_time
RUN_DAYS=$((RUN_UNIX / 60 / 60 / 24))
RUN_HRS=$(((RUN_UNIX / 60 / 60) % 24))
@@ -154,7 +155,7 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
if [ "$SUMMARY_ONLY" = "" ]; then
- echo ">>> $afl_banner ($RUN_DAYS days, $RUN_HRS hrs) fuzzer PID: $fuzzer_pid <<<"
+ echo ">>> $afl_banner instance: $DIR ($RUN_DAYS days, $RUN_HRS hrs) fuzzer PID: $fuzzer_pid <<<"
echo
fi
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 25c1f6bc..40c328ec 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -8,6 +8,12 @@
- ensure temporary file descriptor is closed when not used
- added `AFL_NO_WARN_INSTABILITY`
- added `AFL_FRIDA_STATS_INTERVAL`
+ - added time_wo_finds to fuzzer_stats
+ - fixed a crash in pizza (1st april easter egg) mode. Sorry for
+ everyone who was affected!
+ - allow pizza mode to be disabled when AFL_PIZZA_MODE is set to -1
+ - add -z switch to prefer new coverage findings in seed selection
+ - print name of custom mutator in UI
- afl-cc:
- add CFI sanitizer variant to gcc targets
- llvm 16 support (thanks to @devnexen!)
diff --git a/docs/afl-fuzz_approach.md b/docs/afl-fuzz_approach.md
index 6af39769..cb173f10 100644
--- a/docs/afl-fuzz_approach.md
+++ b/docs/afl-fuzz_approach.md
@@ -483,6 +483,7 @@ directory. This includes:
- `fuzzer_pid` - PID of the fuzzer process
- `cycles_done` - queue cycles completed so far
- `cycles_wo_finds` - number of cycles without any new paths found
+- `time_wo_finds` - longest time in seconds no new path was found
- `execs_done` - number of execve() calls attempted
- `execs_per_sec` - overall number of execs per second
- `corpus_count` - total number of entries in the queue
diff --git a/docs/env_variables.md b/docs/env_variables.md
index c9dc1bbd..a6a0ae44 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -581,7 +581,7 @@ checks or alter some of the more exotic semantics of the tool:
constructors in your target, you can set `AFL_EARLY_FORKSERVER`.
Note that this is not a compile time option but a runtime option :-)
- - Set `AFL_PIZZA_MODE` to 1 to enable the April 1st stats menu, set to 0
+ - Set `AFL_PIZZA_MODE` to 1 to enable the April 1st stats menu, set to -1
to disable although it is 1st of April.
- If you need a specific interval to update fuzzer_stats file, you can
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 6a8e8b5d..7ff3315b 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -398,8 +398,8 @@ typedef struct afl_env_vars {
afl_bench_until_crash, afl_debug_child, afl_autoresume, afl_cal_fast,
afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new,
afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems,
- afl_keep_timeouts, afl_pizza_mode, afl_no_crash_readme,
- afl_ignore_timeouts, afl_no_startup_calibration, afl_no_warn_instability;
+ afl_keep_timeouts, afl_no_crash_readme, afl_ignore_timeouts,
+ afl_no_startup_calibration, afl_no_warn_instability;
u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path,
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload,
@@ -408,6 +408,8 @@ typedef struct afl_env_vars {
*afl_testcache_entries, *afl_child_kill_signal, *afl_fsrv_kill_signal,
*afl_target_env, *afl_persistent_record, *afl_exit_on_time;
+ s32 afl_pizza_mode;
+
} afl_env_vars_t;
struct afl_pass_stat {
@@ -499,7 +501,8 @@ typedef struct afl_state {
custom_splice_optout, /* Custom mutator no splice buffer */
is_main_node, /* if this is the main node */
is_secondary_node, /* if this is a secondary instance */
- pizza_is_served; /* pizza mode */
+ pizza_is_served, /* pizza mode */
+ prefer_new; /* prefer new queue entries */
u32 stats_update_freq; /* Stats update frequency (execs) */
@@ -591,6 +594,7 @@ typedef struct afl_state {
last_find_time, /* Time for most recent path (ms) */
last_crash_time, /* Time for most recent crash (ms) */
last_hang_time, /* Time for most recent hang (ms) */
+ longest_find_time, /* Longest time taken for a find */
exit_on_time, /* Delay to exit if no new paths */
sync_time; /* Sync time (ms) */
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index f82224ed..b024179a 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -431,6 +431,8 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
if ((afl_global_id = atoi(ptr)) < 0)
FATAL("AFL_LLVM_LTO_STARTID value of \"%s\" is negative\n", ptr);
+ if (afl_global_id < 4) { afl_global_id = 4; }
+
if ((ptr = getenv("AFL_LLVM_DOCUMENT_IDS")) != NULL) {
dFile.open(ptr, std::ofstream::out | std::ofstream::app);
@@ -1779,6 +1781,7 @@ INITIALIZE_PASS_END(ModuleSanitizerCoverageLTOLegacyPass, "sancov-lto",
"Pass for instrumenting coverage on functions", false,
false)
+#if LLVM_VERSION_MAJOR < 16
static void registerLTOPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
@@ -1793,8 +1796,9 @@ static RegisterStandardPasses RegisterCompTransPass(
static RegisterStandardPasses RegisterCompTransPass0(
PassManagerBuilder::EP_EnabledOnOptLevel0, registerLTOPass);
-#if LLVM_VERSION_MAJOR >= 11
+ #if LLVM_VERSION_MAJOR >= 11
static RegisterStandardPasses RegisterCompTransPassLTO(
PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerLTOPass);
+ #endif
#endif
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index a88396d4..26fc7256 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -1536,7 +1536,7 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
}
- if (start == stop || *start) return;
+ if (start == stop || *start) { return; }
x = getenv("AFL_INST_RATIO");
if (x) {
@@ -1563,12 +1563,13 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
"[-] FATAL: forkserver is already up, but an instrumented dlopen() "
"library loaded afterwards. You must AFL_PRELOAD such libraries to "
"be able to fuzz them or LD_PRELOAD to run outside of afl-fuzz.\n"
- "To ignore this set AFL_IGNORE_PROBLEMS=1.\n");
+ "To ignore this set AFL_IGNORE_PROBLEMS=1 but this will be bad for "
+ "coverage.\n");
abort();
} else {
- static u32 offset = 4;
+ static u32 offset = 5;
while (start < stop) {
@@ -1582,7 +1583,7 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
}
- if (unlikely(++offset >= __afl_final_loc)) { offset = 4; }
+ if (unlikely(++offset >= __afl_final_loc)) { offset = 5; }
}
@@ -1596,7 +1597,7 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
to avoid duplicate calls (which can happen as an artifact of the underlying
implementation in LLVM). */
- if (__afl_final_loc < 3) __afl_final_loc = 3; // we skip the first 4 entries
+ if (__afl_final_loc < 5) __afl_final_loc = 5; // we skip the first 5 entries
*(start++) = ++__afl_final_loc;
diff --git a/instrumentation/afl-llvm-common.cc b/instrumentation/afl-llvm-common.cc
index dc34d191..5d82aa25 100644
--- a/instrumentation/afl-llvm-common.cc
+++ b/instrumentation/afl-llvm-common.cc
@@ -289,6 +289,7 @@ void scanForDangerousFunctions(llvm::Module *M) {
StringRef ifunc_name = IF.getName();
Constant *r = IF.getResolver();
+ if (r->getNumOperands() == 0) { continue; }
StringRef r_name = cast<Function>(r->getOperand(0))->getName();
if (!be_quiet)
fprintf(stderr,
diff --git a/src/afl-as.c b/src/afl-as.c
index a0eb612f..772e31b3 100644
--- a/src/afl-as.c
+++ b/src/afl-as.c
@@ -93,7 +93,7 @@ static u8 use_64bit = 0;
static void edit_params(int argc, char **argv) {
u8 *tmp_dir = getenv("TMPDIR"), *afl_as = getenv("AFL_AS");
- u32 i;
+ u32 i, input_index;
#ifdef __APPLE__
@@ -142,7 +142,23 @@ static void edit_params(int argc, char **argv) {
as_params[argc] = 0;
- for (i = 1; (s32)i < argc - 1; i++) {
+ /* Find the input file. It's usually located near the end.
+ Assume there won't be any arguments referring to files after the input
+ file, e.g. as input.s -o output.o */
+ for (input_index = argc - 1; input_index > 0; input_index--) {
+
+ input_file = argv[input_index];
+ /* Clang may add debug arguments after the input file. */
+ if (strncmp(input_file, "-g", 2)) break;
+
+ }
+
+ if (input_index == 0)
+ FATAL("Could not find input file (not called through afl-gcc?)");
+
+ for (i = 1; (s32)i < argc; i++) {
+
+ if (i == input_index) continue;
if (!strcmp(argv[i], "--64")) {
@@ -194,8 +210,6 @@ static void edit_params(int argc, char **argv) {
#endif /* __APPLE__ */
- input_file = argv[argc - 1];
-
if (input_file[0] == '-') {
if (!strcmp(input_file + 1, "-version")) {
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 7b059d40..7f15ad76 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -1101,37 +1101,45 @@ static void edit_params(u32 argc, char **argv, char **envp) {
if (!have_c) 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:
+ /* As documented in instrumentation/README.persistent_mode.md, deferred
+ forkserver initialization and persistent mode are not available in afl-gcc
+ and afl-clang. */
+ if (compiler_mode != GCC && compiler_mode != CLANG) {
- 1) We need to convince the compiler not to optimize out the signature.
- This is done with __attribute__((used)).
+ cc_params[cc_par_cnt++] = "-D__AFL_HAVE_MANUAL_CONTROL=1";
- 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.
+ /* 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:
- 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.
+ 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.
- 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[1048576];"
- "unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt;";
+ 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[1048576];"
+ "unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt;";
+
+ }
if (plusplus_mode) {
@@ -1169,35 +1177,39 @@ static void edit_params(u32 argc, char **argv, char **envp) {
"(*__afl_fuzz_len = read(0, __afl_fuzz_alt_ptr, 1048576)) == 0xffffffff "
"? 0 : *__afl_fuzz_len)";
- cc_params[cc_par_cnt++] =
- "-D__AFL_LOOP(_A)="
- "({ static volatile char *_B __attribute__((used,unused)); "
- " _B = (char*)\"" PERSIST_SIG
- "\"; "
- "extern int __afl_connected;"
+ if (compiler_mode != GCC && compiler_mode != CLANG) {
+
+ cc_params[cc_par_cnt++] =
+ "-D__AFL_LOOP(_A)="
+ "({ static volatile const char *_B __attribute__((used,unused)); "
+ " _B = (const char*)\"" PERSIST_SIG
+ "\"; "
+ "extern int __afl_connected;"
#ifdef __APPLE__
- "__attribute__((visibility(\"default\"))) "
- "int _L(unsigned int) __asm__(\"___afl_persistent_loop\"); "
+ "__attribute__((visibility(\"default\"))) "
+ "int _L(unsigned int) __asm__(\"___afl_persistent_loop\"); "
#else
- "__attribute__((visibility(\"default\"))) "
- "int _L(unsigned int) __asm__(\"__afl_persistent_loop\"); "
+ "__attribute__((visibility(\"default\"))) "
+ "int _L(unsigned int) __asm__(\"__afl_persistent_loop\"); "
#endif /* ^__APPLE__ */
- // if afl is connected, we run _A times, else once.
- "_L(__afl_connected ? _A : 1); })";
+ // if afl is connected, we run _A times, else once.
+ "_L(__afl_connected ? _A : 1); })";
- cc_params[cc_par_cnt++] =
- "-D__AFL_INIT()="
- "do { static volatile char *_A __attribute__((used,unused)); "
- " _A = (char*)\"" DEFER_SIG
- "\"; "
+ cc_params[cc_par_cnt++] =
+ "-D__AFL_INIT()="
+ "do { static volatile const char *_A __attribute__((used,unused)); "
+ " _A = (const char*)\"" DEFER_SIG
+ "\"; "
#ifdef __APPLE__
- "__attribute__((visibility(\"default\"))) "
- "void _I(void) __asm__(\"___afl_manual_init\"); "
+ "__attribute__((visibility(\"default\"))) "
+ "void _I(void) __asm__(\"___afl_manual_init\"); "
#else
- "__attribute__((visibility(\"default\"))) "
- "void _I(void) __asm__(\"__afl_manual_init\"); "
+ "__attribute__((visibility(\"default\"))) "
+ "void _I(void) __asm__(\"__afl_manual_init\"); "
#endif /* ^__APPLE__ */
- "_I(); } while (0)";
+ "_I(); } while (0)";
+
+ }
if (x_set) {
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index d9c792d1..556bb5d1 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -465,7 +465,8 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
u8 fn[PATH_MAX];
u8 *queue_fn = "";
- u8 new_bits = 0, keeping = 0, res, classified = 0, is_timeout = 0;
+ u8 new_bits = 0, keeping = 0, res, classified = 0, is_timeout = 0,
+ need_hash = 1;
s32 fd;
u64 cksum = 0;
@@ -477,6 +478,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
classify_counts(&afl->fsrv);
classified = 1;
+ need_hash = 0;
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
@@ -499,6 +501,8 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
new_bits = has_new_bits_unclassified(afl, afl->virgin_bits);
+ if (unlikely(new_bits)) { classified = 1; }
+
}
if (likely(!new_bits)) {
@@ -565,12 +569,12 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
}
- if (unlikely(!classified && new_bits)) {
+ if (unlikely(need_hash && new_bits)) {
/* due to classify counts we have to recalculate the checksum */
afl->queue_top->exec_cksum =
hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
- classified = 1;
+ need_hash = 0;
}
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index 9ea46e7a..64dbe7c6 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -179,11 +179,19 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
void *dh;
struct custom_mutator *mutator = ck_alloc(sizeof(struct custom_mutator));
- mutator->name = fn;
- if (memchr(fn, '/', strlen(fn)))
- mutator->name_short = strrchr(fn, '/') + 1;
- else
+ if (memchr(fn, '/', strlen(fn))) {
+
+ mutator->name_short = strdup(strrchr(fn, '/') + 1);
+
+ } else {
+
mutator->name_short = strdup(fn);
+
+ }
+
+ if (strlen(mutator->name_short) > 22) { mutator->name_short[21] = 0; }
+
+ mutator->name = fn;
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 be526dbd..ee562f96 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -1931,6 +1931,7 @@ custom_mutator_stage:
if (el->afl_custom_fuzz) {
afl->current_custom_fuzz = el;
+ afl->stage_name = el->name_short;
if (el->afl_custom_fuzz_count) {
@@ -2071,7 +2072,7 @@ havoc_stage:
afl->stage_short = "havoc";
afl->stage_max = ((doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) *
perf_score / afl->havoc_div) >>
- 7;
+ 8;
} else {
@@ -2080,11 +2081,11 @@ havoc_stage:
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) >> 7;
+ afl->stage_max = (SPLICE_HAVOC * perf_score / afl->havoc_div) >> 8;
}
- if (afl->stage_max < HAVOC_MIN) { afl->stage_max = HAVOC_MIN; }
+ if (unlikely(afl->stage_max < HAVOC_MIN)) { afl->stage_max = HAVOC_MIN; }
temp_len = len;
@@ -4640,7 +4641,7 @@ pacemaker_fuzzing:
MOpt_globals.splice_stageformat, splice_cycle);
afl->stage_name = afl->stage_name_buf;
afl->stage_short = MOpt_globals.splice_stagenameshort;
- afl->stage_max = (SPLICE_HAVOC * perf_score / afl->havoc_div) >> 7;
+ afl->stage_max = (SPLICE_HAVOC * perf_score / afl->havoc_div) >> 8;
}
diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c
index 2799268b..673e5a6c 100644
--- a/src/afl-fuzz-python.c
+++ b/src/afl-fuzz-python.c
@@ -414,10 +414,21 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl,
struct custom_mutator *mutator;
mutator = ck_alloc(sizeof(struct custom_mutator));
-
mutator->name = module_name;
ACTF("Loading Python mutator library from '%s'...", module_name);
+ if (memchr(module_name, '/', strlen(module_name))) {
+
+ mutator->name_short = strdup(strrchr(module_name, '/') + 1);
+
+ } else {
+
+ mutator->name_short = strdup(module_name);
+
+ }
+
+ if (strlen(mutator->name_short) > 22) { mutator->name_short[21] = 0; }
+
py_mutator_t *py_mutator;
py_mutator = init_py_module(afl, module_name);
mutator->data = py_mutator;
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index 4eb55bb3..6fc3c743 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -74,7 +74,8 @@ 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 *= (1 + (q->tc_ref / avg_top_size));
- if (unlikely(weight < 1.0)) { weight = 1.0; }
+
+ if (unlikely(weight < 0.1)) { weight = 0.1; }
if (unlikely(q->favored)) { weight *= 5; }
if (unlikely(!q->was_fuzzed)) { weight *= 2; }
@@ -148,6 +149,26 @@ void create_alias_table(afl_state_t *afl) {
}
+ if (unlikely(afl->prefer_new) && afl->queued_discovered) {
+
+ double avg_weight = sum / active;
+
+ for (i = n - afl->queued_discovered; i < n; i++) {
+
+ struct queue_entry *q = afl->queue_buf[i];
+
+ if (likely(!q->disabled) && q->weight > avg_weight) {
+
+ double prev_weight = q->weight;
+ q->weight *= (2.0 * (i / n));
+ sum += (q->weight - prev_weight);
+
+ }
+
+ }
+
+ }
+
for (i = 0; i < n; i++) {
// weight is always 0 for disabled entries
@@ -577,7 +598,24 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
queue_buf[afl->queued_items - 1] = q;
q->id = afl->queued_items - 1;
- afl->last_find_time = get_cur_time();
+ u64 cur_time = get_cur_time();
+
+ if (likely(afl->start_time) &&
+ unlikely(afl->longest_find_time < cur_time - afl->last_find_time)) {
+
+ if (unlikely(!afl->last_find_time)) {
+
+ afl->longest_find_time = cur_time - afl->start_time;
+
+ } else {
+
+ afl->longest_find_time = cur_time - afl->last_find_time;
+
+ }
+
+ }
+
+ afl->last_find_time = cur_time;
if (afl->custom_mutators_count) {
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index f9aa5cfe..46b67def 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -648,7 +648,15 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
}
- if (afl->afl_env.afl_pizza_mode) { afl->pizza_is_served = 1; }
+ if (afl->afl_env.afl_pizza_mode > 0) {
+
+ afl->pizza_is_served = 1;
+
+ } else if (afl->afl_env.afl_pizza_mode < 0) {
+
+ OKF("Pizza easter egg mode is now disabled.");
+
+ }
if (issue_detected) { sleep(2); }
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index f53fd610..07157bf7 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -251,6 +251,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
"fuzzer_pid : %u\n"
"cycles_done : %llu\n"
"cycles_wo_finds : %llu\n"
+ "time_wo_finds : %llu\n"
"execs_done : %llu\n"
"execs_per_sec : %0.02f\n"
"execs_ps_last_min : %0.02f\n"
@@ -291,6 +292,11 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
(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->longest_find_time > cur_time - afl->last_find_time
+ ? afl->longest_find_time / 1000
+ : ((afl->start_time == 0 || afl->last_find_time == 0)
+ ? 0
+ : (cur_time - afl->last_find_time) / 1000),
afl->fsrv.total_execs,
afl->fsrv.total_execs /
((double)(afl->prev_run_time + get_cur_time() - afl->start_time) /
@@ -747,20 +753,20 @@ void show_stats_normal(afl_state_t *afl) {
#ifdef __linux__
if (afl->fsrv.nyx_mode) {
- sprintf(banner + banner_pad,
- "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s] - Nyx",
- afl->crash_mode ? cPIN "peruvian were-rabbit"
- : cYEL "american fuzzy lop",
- si, afl->use_banner, afl->power_name);
+ snprintf(banner + banner_pad, sizeof(banner) - banner_pad,
+ "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s] - Nyx",
+ afl->crash_mode ? cPIN "peruvian were-rabbit"
+ : cYEL "american fuzzy lop",
+ si, afl->use_banner, afl->power_name);
} else {
#endif
- sprintf(banner + banner_pad,
- "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]",
- afl->crash_mode ? cPIN "peruvian were-rabbit"
- : cYEL "american fuzzy lop",
- si, afl->use_banner, afl->power_name);
+ snprintf(banner + banner_pad, sizeof(banner) - banner_pad,
+ "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]",
+ afl->crash_mode ? cPIN "peruvian were-rabbit"
+ : cYEL "american fuzzy lop",
+ si, afl->use_banner, afl->power_name);
#ifdef __linux__
@@ -1551,20 +1557,22 @@ void show_stats_pizza(afl_state_t *afl) {
#ifdef __linux__
if (afl->fsrv.nyx_mode) {
- sprintf(banner + banner_pad,
- "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s] - Nyx",
- afl->crash_mode ? cPIN "Mozzarbella Pizzeria table booking system"
- : cYEL "Mozzarbella Pizzeria management system",
- si, afl->use_banner, afl->power_name);
+ snprintf(banner + banner_pad, sizeof(banner) - banner_pad,
+ "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s] - Nyx",
+ afl->crash_mode ? cPIN
+ "Mozzarbella Pizzeria table booking system"
+ : cYEL "Mozzarbella Pizzeria management system",
+ si, afl->use_banner, afl->power_name);
} else {
#endif
- sprintf(banner + banner_pad,
- "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]",
- afl->crash_mode ? cPIN "Mozzarbella Pizzeria table booking system"
- : cYEL "Mozzarbella Pizzeria management system",
- si, afl->use_banner, afl->power_name);
+ snprintf(banner + banner_pad, sizeof(banner) - banner_pad,
+ "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]",
+ afl->crash_mode ? cPIN
+ "Mozzarbella Pizzeria table booking system"
+ : cYEL "Mozzarbella Pizzeria management system",
+ si, afl->use_banner, afl->power_name);
#ifdef __linux__
@@ -1795,10 +1803,10 @@ void show_stats_pizza(afl_state_t *afl) {
/* Show a warning about slow execution. */
- if (afl->stats_avg_exec < 100) {
+ if (afl->stats_avg_exec < 20) {
sprintf(tmp, "%s/sec (%s)", u_stringify_float(IB(0), afl->stats_avg_exec),
- afl->stats_avg_exec < 20 ? "zzzz..." : "Gennarino is at it again!");
+ "zzzz...");
SAYF(bV bSTOP " pizza making speed : " cLRD
"%-22s ",
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index d7708fdf..a0c322da 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -132,6 +132,7 @@ static void usage(u8 *argv0, int more_help) {
" fast(default), explore, exploit, seek, rare, mmopt, "
"coe, lin\n"
" quad -- see docs/FAQ.md for more information\n"
+ " -z - prefer new coverage findings when fuzzing\n"
" -f file - location read by the fuzzed program (default: stdin "
"or @@)\n"
" -t msec - timeout for each run (auto-scaled, default %u ms). "
@@ -165,7 +166,6 @@ static void usage(u8 *argv0, int more_help) {
" pacemaker mode (minutes of no new finds). 0 = "
"immediately,\n"
" -1 = immediately and together with normal mutation.\n"
- " See docs/README.MOpt.md\n"
" -c program - enable CmpLog by specifying a binary compiled for "
"it.\n"
" if using QEMU/FRIDA or the fuzzing target is "
@@ -556,7 +556,7 @@ int main(int argc, char **argv_orig, char **envp) {
while (
(opt = getopt(
argc, argv,
- "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:YZ")) >
+ "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:YzZ")) >
0) {
switch (opt) {
@@ -569,6 +569,10 @@ int main(int argc, char **argv_orig, char **envp) {
afl->max_length = atoi(optarg);
break;
+ case 'z':
+ afl->prefer_new = 1;
+ break;
+
case 'Z':
afl->old_seed_selection = 1;
break;
@@ -1344,8 +1348,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 defaults and behaviours - see "
- "README.md");
+ OKF("NOTE: afl++ >= v3 has changed defaults and behaviours - see README.md");
#ifdef __linux__
if (afl->fsrv.nyx_mode) {
@@ -2497,10 +2500,22 @@ int main(int argc, char **argv_orig, char **envp) {
}
#ifdef INTROSPECTION
- fprintf(afl->introspection_file,
- "CYCLE cycle=%llu cycle_wo_finds=%llu expand_havoc=%u queue=%u\n",
- afl->queue_cycle, afl->cycles_wo_finds, afl->expand_havoc,
- afl->queued_items);
+ {
+
+ u64 cur_time = get_cur_time();
+ fprintf(afl->introspection_file,
+ "CYCLE cycle=%llu cycle_wo_finds=%llu time_wo_finds=%llu "
+ "expand_havoc=%u queue=%u\n",
+ afl->queue_cycle, afl->cycles_wo_finds,
+ afl->longest_find_time > cur_time - afl->last_find_time
+ ? afl->longest_find_time / 1000
+ : ((afl->start_time == 0 || afl->last_find_time == 0)
+ ? 0
+ : (cur_time - afl->last_find_time) / 1000),
+ afl->expand_havoc, afl->queued_items);
+
+ }
+
#endif
if (afl->cycle_schedules) {
diff --git a/test/test-basic.sh b/test/test-basic.sh
index 53de8c64..5bb2ca28 100755
--- a/test/test-basic.sh
+++ b/test/test-basic.sh
@@ -133,7 +133,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
SKIP=
test -e ../${AFL_CLANG} -a -e ../afl-showmap -a -e ../afl-fuzz && {
../${AFL_CLANG} -v 2>&1 | grep -qi "clang version" && {
- ../${AFL_CLANG} -o test-instr.plain -O0 ../test-instr.c > /dev/null 2>&1
+ ../${AFL_CLANG} -O0 -o test-instr.plain ../test-instr.c > /dev/null 2>&1
AFL_HARDEN=1 ../${AFL_CLANG} -o test-compcov.harden test-compcov.c > /dev/null 2>&1
test -e test-instr.plain && {
$ECHO "$GREEN[+] ${AFL_CLANG} compilation succeeded"
diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c
index f08c9864..ec304c8c 100644
--- a/utils/aflpp_driver/aflpp_driver.c
+++ b/utils/aflpp_driver/aflpp_driver.c
@@ -1,12 +1,16 @@
-//===- afl_driver.cpp - a glue between AFL++ and libFuzzer ------*- C++ -* ===//
-//===----------------------------------------------------------------------===//
+//
+// afl_driver.cpp - a glue between AFL++ and LLVMFuzzerTestOneInput harnesses
+//
-/* This file allows to fuzz libFuzzer-style target functions
+/*
+
+ This file allows to fuzz libFuzzer-style target functions
(LLVMFuzzerTestOneInput) with AFL++ using persistent in-memory fuzzing.
Usage:
-################################################################################
-cat << EOF > test_fuzzer.cc
+
+# Example target:
+$ cat << EOF > test_fuzzer.cc
#include <stddef.h>
#include <stdint.h>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
@@ -20,16 +24,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
}
EOF
-# Build your target with -fsanitize-coverage=trace-pc-guard using fresh clang.
-clang -c aflpp_driver.c
-# Build afl-compiler-rt.o.c from the AFL distribution.
-clang -c $AFL_HOME/instrumentation/afl-compiler-rt.o.c
-# Build this file, link it with afl-compiler-rt.o.o and the target code.
-afl-clang-fast -o test_fuzzer test_fuzzer.cc afl-compiler-rt.o aflpp_driver.o
+
+# Build your target with afl-cc -fsanitize=fuzzer
+$ afl-c++ -fsanitize=fuzzer -o test_fuzzer test_fuzzer.cc
# Run AFL:
-rm -rf IN OUT; mkdir IN OUT; echo z > IN/z;
-$AFL_HOME/afl-fuzz -i IN -o OUT ./a.out
-################################################################################
+$ mkdir -p in ; echo z > in/foo;
+$ afl-fuzz -i in -o out -- ./test_fuzzer
+
*/
#include <assert.h>
@@ -71,8 +72,8 @@ extern unsigned int __afl_map_size;
__attribute__((weak)) int LLVMFuzzerTestOneInput(const uint8_t *Data,
size_t Size);
__attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv);
-int LLVMFuzzerRunDriver(int *argc, char ***argv,
- int (*callback)(const uint8_t *data, size_t size));
+__attribute__((weak)) int LLVMFuzzerRunDriver(
+ int *argc, char ***argv, int (*callback)(const uint8_t *data, size_t size));
// Default nop ASan hooks for manual poisoning when not linking the ASan
// runtime
@@ -196,7 +197,8 @@ static void maybe_close_fd_mask() {
// Define LLVMFuzzerMutate to avoid link failures for targets that use it
// with libFuzzer's LLVMFuzzerCustomMutator.
-size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) {
+__attribute__((weak)) size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size,
+ size_t MaxSize) {
// assert(false && "LLVMFuzzerMutate should not be called from afl_driver");
return 0;
@@ -280,8 +282,9 @@ __attribute__((weak)) int main(int argc, char **argv) {
}
-int LLVMFuzzerRunDriver(int *argcp, char ***argvp,
- int (*callback)(const uint8_t *data, size_t size)) {
+__attribute__((weak)) int LLVMFuzzerRunDriver(
+ int *argcp, char ***argvp,
+ int (*callback)(const uint8_t *data, size_t size)) {
int argc = *argcp;
char **argv = *argvp;