about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2020-08-06 19:43:56 +0200
committerGitHub <noreply@github.com>2020-08-06 19:43:56 +0200
commitbd1d148f83d0c32d5bcc1d86a4109cf87a17b276 (patch)
tree6e3afa0d316f2600107955237e269dad0668e59f
parentc4e5f75728f18949f754634b669a14c92ad0f5c4 (diff)
parent7e0c9a36ef468dcc74e5658d33cf06b5798648fc (diff)
downloadafl++-bd1d148f83d0c32d5bcc1d86a4109cf87a17b276.tar.gz
Merge pull request #494 from AFLplusplus/test
aflpp driver fix for early callers
-rw-r--r--examples/aflpp_driver/aflpp_driver.c41
-rw-r--r--llvm_mode/README.persistent_mode.md26
2 files changed, 59 insertions, 8 deletions
diff --git a/examples/aflpp_driver/aflpp_driver.c b/examples/aflpp_driver/aflpp_driver.c
index 86c7a69f..2b35a46f 100644
--- a/examples/aflpp_driver/aflpp_driver.c
+++ b/examples/aflpp_driver/aflpp_driver.c
@@ -56,6 +56,7 @@ If 1, close stdout at startup. If 2 close stderr; if 3 close both.
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <sys/mman.h>
 
 #include "config.h"
 
@@ -63,6 +64,12 @@ If 1, close stdout at startup. If 2 close stderr; if 3 close both.
   #include "hash.h"
 #endif
 
+#ifndef MAP_FIXED_NOREPLACE
+#define MAP_FIXED_NOREPLACE	0x100000
+#endif
+
+#define MAX_DUMMY_SIZE 256000
+
 // Platform detection. Copied from FuzzerInternal.h
 #ifdef __linux__
   #define LIBFUZZER_LINUX 1
@@ -101,6 +108,7 @@ If 1, close stdout at startup. If 2 close stderr; if 3 close both.
 int                   __afl_sharedmem_fuzzing = 1;
 extern unsigned int * __afl_fuzz_len;
 extern unsigned char *__afl_fuzz_ptr;
+extern unsigned char *__afl_area_ptr;
 
 // libFuzzer interface is thin, so we don't include any libFuzzer headers.
 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
@@ -238,26 +246,41 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) {
 
 }
 
+__attribute__((constructor(10))) void __afl_protect(void) {
+  __afl_area_ptr = (unsigned char*) mmap((void *)0x10000, MAX_DUMMY_SIZE, PROT_READ | PROT_WRITE,
+             MAP_FIXED_NOREPLACE | MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+  if ((uint64_t)__afl_area_ptr == -1)
+    __afl_area_ptr = (unsigned char*) mmap((void *)0x10000, MAX_DUMMY_SIZE, PROT_READ | PROT_WRITE,
+             MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+  if ((uint64_t)__afl_area_ptr == -1)
+    __afl_area_ptr = (unsigned char*) mmap(NULL, MAX_DUMMY_SIZE, PROT_READ | PROT_WRITE,
+             MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+}
+
+
 int main(int argc, char **argv) {
 
+  fprintf(stderr, "dummy map is at %p\n", __afl_area_ptr);
+
   printf(
       "======================= INFO =========================\n"
-      "This binary is built for AFL-fuzz.\n"
+      "This binary is built for afl++.\n"
       "To run the target function on individual input(s) execute this:\n"
-      "  %s < INPUT_FILE\n"
-      "or\n"
       "  %s INPUT_FILE1 [INPUT_FILE2 ... ]\n"
       "To fuzz with afl-fuzz execute this:\n"
-      "  afl-fuzz [afl-flags] %s [-N]\n"
-      "afl-fuzz will run N iterations before "
-      "re-spawning the process (default: 1000)\n"
+      "  afl-fuzz [afl-flags] -- %s [-N]\n"
+      "afl-fuzz will run N iterations before re-spawning the process (default: 1000)\n"
       "======================================================\n",
-      argv[0], argv[0], argv[0]);
+      argv[0], argv[0]);
 
   output_file = stderr;
   maybe_duplicate_stderr();
   maybe_close_fd_mask();
-  if (LLVMFuzzerInitialize) LLVMFuzzerInitialize(&argc, &argv);
+  if (LLVMFuzzerInitialize) {
+    fprintf(stderr, "Running LLVMFuzzerInitialize ...\n");
+    LLVMFuzzerInitialize(&argc, &argv);
+    fprintf(stderr, "continue...\n");
+  }
 
   // Do any other expensive one-time initialization here.
 
@@ -275,6 +298,7 @@ int main(int argc, char **argv) {
     //    if (!getenv("AFL_DRIVER_DONT_DEFER")) {
 
     __afl_sharedmem_fuzzing = 0;
+    munmap(__afl_area_ptr, MAX_DUMMY_SIZE);
     __afl_manual_init();
     //    }
     return ExecuteFilesOnyByOne(argc, argv);
@@ -285,6 +309,7 @@ int main(int argc, char **argv) {
   assert(N > 0);
 
   //  if (!getenv("AFL_DRIVER_DONT_DEFER"))
+  munmap(__afl_area_ptr, MAX_DUMMY_SIZE);
   __afl_manual_init();
 
   // Call LLVMFuzzerTestOneInput here so that coverage caused by initialization
diff --git a/llvm_mode/README.persistent_mode.md b/llvm_mode/README.persistent_mode.md
index 4f0bcb2e..5ed59a58 100644
--- a/llvm_mode/README.persistent_mode.md
+++ b/llvm_mode/README.persistent_mode.md
@@ -115,6 +115,32 @@ will keep working normally when compiled with a tool other than afl-clang-fast.
 Finally, recompile the program with afl-clang-fast (afl-gcc or afl-clang will
 *not* generate a deferred-initialization binary) - and you should be all set!
 
+*NOTE:* In the code between `main` and `__AFL_INIT()` should not be any code
+run that is instrumented - otherwise a crash might occure.
+In case this is useful (e.g. for expensive one time initialization) you can
+try to do the following:
+
+Add after the includes:
+```
+extern unsigned char *__afl_area_ptr;
+#define MAX_DUMMY_SIZE 256000
+
+__attribute__((constructor(10))) void __afl_protect(void) {
+#ifdef MAP_FIXED_NOREPLACE
+  __afl_area_ptr = (unsigned char*) mmap((void *)0x10000, MAX_DUMMY_SIZE, PROT_READ | PROT_WRITE, MAP_FIXED_NOREPLACE | MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+  if ((uint64_t)__afl_area_ptr == -1)
+#endif
+    __afl_area_ptr = (unsigned char*) mmap((void *)0x10000, MAX_DUMMY_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+  if ((uint64_t)__afl_area_ptr == -1)
+    __afl_area_ptr = (unsigned char*) mmap(NULL, MAX_DUMMY_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+}
+
+```
+and just before `__AFL_INIT()`:
+```
+  munmap(__afl_area_ptr, MAX_DUMMY_SIZE);
+```
+
 ## 4) persistent mode
 
 Some libraries provide APIs that are stateless, or whose state can be reset in