about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/afl-analyze.c25
-rw-r--r--src/afl-common.c64
-rw-r--r--src/afl-forkserver.c4
-rw-r--r--src/afl-fuzz.c33
-rw-r--r--src/afl-showmap.c25
-rw-r--r--src/afl-tmin.c25
6 files changed, 172 insertions, 4 deletions
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..312d9424 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -326,9 +326,8 @@ 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));
@@ -985,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;
 
@@ -1245,7 +1270,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 +1322,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;