Index: third_party/afl/src/llvm_mode/afl-llvm-rt.o.c |
diff --git a/third_party/afl/src/llvm_mode/afl-llvm-rt.o.c b/third_party/afl/src/llvm_mode/afl-llvm-rt.o.c |
index 8f3f303d54881020d1abe984fa3bb6ab0809402e..e2ef1516fe78c17bd28e0f0704943bf595215037 100644 |
--- a/third_party/afl/src/llvm_mode/afl-llvm-rt.o.c |
+++ b/third_party/afl/src/llvm_mode/afl-llvm-rt.o.c |
@@ -26,6 +26,7 @@ |
#include <stdlib.h> |
#include <signal.h> |
#include <unistd.h> |
+#include <string.h> |
#include <assert.h> |
#include <sys/mman.h> |
@@ -169,18 +170,48 @@ int __afl_persistent_loop(unsigned int max_cnt) { |
if (first_pass) { |
+ /* Make sure that every iteration of __AFL_LOOP() starts with a clean slate. |
+ On subsequent calls, the parent will take care of that, but on the first |
+ iteration, it's our job to erase any trace of whatever happened |
+ before the loop. */ |
+ |
+ if (is_persistent) { |
+ |
+ memset(__afl_area_ptr, 0, MAP_SIZE); |
+ __afl_area_ptr[0] = 1; |
+ __afl_prev_loc = 0; |
+ } |
+ |
cycle_cnt = max_cnt; |
first_pass = 0; |
return 1; |
} |
- if (is_persistent && --cycle_cnt) { |
+ if (is_persistent) { |
- raise(SIGSTOP); |
- return 1; |
+ if (--cycle_cnt) { |
+ |
+ raise(SIGSTOP); |
+ |
+ __afl_area_ptr[0] = 1; |
+ __afl_prev_loc = 0; |
+ |
+ return 1; |
+ |
+ } else { |
+ |
+ /* When exiting __AFL_LOOP(), make sure that the subsequent code that |
+ follows the loop is not traced. We do that by pivoting back to the |
+ dummy output region. */ |
+ |
+ __afl_area_ptr = __afl_area_initial; |
+ |
+ } |
+ |
+ } |
- } else return 0; |
+ return 0; |
} |