about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDominik Maier <domenukk@gmail.com>2020-03-09 21:34:11 +0100
committerDominik Maier <domenukk@gmail.com>2020-03-09 21:34:11 +0100
commit1136e887bdf77ed64bd3eac28bf7f86705dd2a6d (patch)
tree2c7d0e877c1e6f4fb09e268ca0a194c41bc91f23
parent416020daefb2587fe071a456e1dbb8ffbb007e6a (diff)
downloadafl++-1136e887bdf77ed64bd3eac28bf7f86705dd2a6d.tar.gz
now wiht 90% less leaks
-rw-r--r--include/afl-fuzz.h2
-rw-r--r--include/afl-prealloc.h3
-rw-r--r--include/common.h3
-rw-r--r--src/afl-common.c84
-rw-r--r--src/afl-fuzz-cmplog.c16
-rw-r--r--src/afl-fuzz.c6
-rw-r--r--src/afl-showmap.c28
-rw-r--r--src/afl-tmin.c13
8 files changed, 64 insertions, 91 deletions
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index d49898dd..b83d224b 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -515,7 +515,7 @@ typedef struct afl_state {
 
   /* CmpLog */
 
-  u8* cmplog_binary;
+  char* cmplog_binary;
   s32 cmplog_child_pid, cmplog_fsrv_pid;
 
   /* Custom mutators */
diff --git a/include/afl-prealloc.h b/include/afl-prealloc.h
index 02de0344..ab86f0d7 100644
--- a/include/afl-prealloc.h
+++ b/include/afl-prealloc.h
@@ -32,6 +32,7 @@
 #include <string.h>
 
 #include "debug.h"
+#include "alloc-inl.h"
 
 typedef enum prealloc_status {
 
@@ -123,7 +124,7 @@ typedef enum prealloc_status {
       case PRE_STATUS_MALLOC: {                   \
                                                   \
         (el_ptr)->pre_status = PRE_STATUS_UNUSED; \
-        ck_free((el_ptr));                        \
+        DFL_ck_free((el_ptr));                    \
         break;                                    \
                                                   \
       }                                           \
diff --git a/include/common.h b/include/common.h
index 5afc5ee3..5d0e7266 100644
--- a/include/common.h
+++ b/include/common.h
@@ -34,6 +34,9 @@
 void detect_file_args(char** argv, u8* prog_in, u8 *use_stdin);
 void check_environment_vars(char** env);
 
+char **argv_cpy_dup(int argc, char **argv);
+void argv_cpy_free(char **argv);
+
 char** get_qemu_argv(u8* own_loc, u8** target_path_p, int argc, char** argv);
 char** get_wine_argv(u8* own_loc, u8** target_path_p, int argc, char** argv);
 char*  get_afl_env(char* env);
diff --git a/src/afl-common.c b/src/afl-common.c
index cce878f1..44f07827 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -87,12 +87,11 @@ void detect_file_args(char** argv, u8* prog_in, u8 *use_stdin) {
 
         /* Construct a replacement argv value. */
 
-        // TODO: n_arg is never freed
-
         *aa_loc = 0;
         n_arg = alloc_printf("%s%s%s", argv[i], aa_subst, aa_loc + 2);
+        ck_free(argv[i]);
         argv[i] = n_arg;
-        *aa_loc = '@';
+        //*aa_loc = '@';
 
         if (prog_in[0] != '/') ck_free(aa_subst);
 
@@ -108,90 +107,31 @@ void detect_file_args(char** argv, u8* prog_in, u8 *use_stdin) {
 
 }
 
+/* duplicate the system argv so that 
+  we can edit (and free!) it later */
 
-char **create_file_args(int argc, char** argv, u8* prog_in, u8 *use_stdin) {
+char **argv_cpy_dup(int argc, char** argv) {
 
   u32 i = 0;
 
-  char **ret = malloc((argc + 1) * sizeof(char));
-
-#ifdef __GLIBC__
-  u8* cwd = getcwd(NULL, 0);                /* non portable glibc extension */
-#else
-  u8*   cwd;
-  char* buf;
-  long  size = pathconf(".", _PC_PATH_MAX);
-  if ((buf = (char*)malloc((size_t)size)) != NULL) {
-
-    cwd = getcwd(buf, (size_t)size);                    /* portable version */
-    ck_free(buf);
-
-  } else {
-
-    cwd = 0;                                          /* for dumb compilers */
-    PFATAL("getcwd() failed");
-
-  }
-
-#endif
-
-  if (!cwd) PFATAL("getcwd() failed");
-
-  // TODO: free allocs below... somewhere.
-
-  while (argv[i]) {
-
-    u8* aa_loc = strstr(argv[i], "@@");
-
-    if (aa_loc) {
-
-      u8 *aa_subst, *n_arg;
-
-      if (!prog_in) FATAL("@@ syntax is not supported by this tool.");
-
-      *use_stdin = 0;
-
-      if (prog_in[0] != 0) {  // not afl-showmap special case
-
-        /* Be sure that we're always using fully-qualified paths. */
-
-        if (prog_in[0] == '/')
-          aa_subst = prog_in;
-        else
-          aa_subst = alloc_printf("%s/%s", cwd, prog_in);
-
-        /* Construct a replacement argv value. */
+  char **ret = ck_alloc((argc + 1) * sizeof(char *));
 
-        // TODO: n_arg is never freed
-
-        *aa_loc = 0;
-        n_arg = alloc_printf("%s%s%s", argv[i], aa_subst, aa_loc + 2);
-        ret[i] = n_arg;
-        *aa_loc = '@';
-
-        if (prog_in[0] != '/') ck_free(aa_subst);
-
-        i++;
-        continue;
-
-      }
-
-    }
+  for (i = 0; i < argc; i++) {
 
     ret[i] = ck_strdup(argv[i]);
-    i++;
 
   }
-  ret[i] = NULL;
 
-  ck_free(cwd);                                                 /* not tracked */
+  ret[i] = NULL;
 
   return ret;
+
 }
 
 /* frees all args in the given argv, 
-   previously created by create_file_args */
-void destroy_file_args(char **argv) {
+   previously created by argv_cpy_dup */
+
+void argv_cpy_free(char **argv) {
 
   u32 i=0;
   while(argv[i]) {
diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c
index 3749330b..0a4c3a9e 100644
--- a/src/afl-fuzz-cmplog.c
+++ b/src/afl-fuzz-cmplog.c
@@ -151,7 +151,13 @@ void init_cmplog_forkserver(afl_state_t *afl) {
 
     setenv("___AFL_EINS_ZWEI_POLIZEI___", "1", 1);
 
-    if (!afl->qemu_mode) afl->argv[0] = afl->cmplog_binary;
+    if (!afl->qemu_mode && afl->argv[0] != afl->cmplog_binary) {
+
+      ck_free(afl->argv[0]);
+      afl->argv[0] = afl->cmplog_binary;
+
+    }
+
     execv(afl->argv[0], afl->argv);
 
     /* Use a distinctive bitmap signature to tell the parent about execv()
@@ -448,7 +454,13 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
 
       setenv("___AFL_EINS_ZWEI_POLIZEI___", "1", 1);
 
-      if (!afl->qemu_mode) afl->argv[0] = afl->cmplog_binary;
+      if (!afl->qemu_mode && afl->argv[0] != afl->cmplog_binary) {
+        
+        ck_free(afl->argv[0]);
+        afl->argv[0] = afl->cmplog_binary;
+
+      }
+
       execv(afl->argv[0], afl->argv);
 
       /* Use a distinctive bitmap value to tell the parent about execv()
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 4b6ced7a..5df4088f 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -224,7 +224,7 @@ static int stricmp(char const* a, char const* b) {
 
 /* Main entry point */
 
-int main(int argc, char** argv, char** envp) {
+int main(int argc, char** argv_orig, char** envp) {
 
   s32    opt;
   u64    prev_queued = 0;
@@ -237,6 +237,8 @@ int main(int argc, char** argv, char** envp) {
   struct timeval  tv;
   struct timezone tz;
 
+  char **argv = argv_cpy_dup(argc, argv_orig);
+
   afl_state_t* afl = calloc(1, sizeof(afl_state_t));
   if (!afl) { FATAL("Could not create afl state"); }
 
@@ -1173,6 +1175,8 @@ stop_fuzzing:
   ck_free(afl->sync_id);
   ck_free(afl);
 
+  argv_cpy_free(argv);
+
   alloc_report();
 
   OKF("We're done here. Have a nice day!\n");
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 771fa733..bed249c4 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -61,8 +61,9 @@
 
 u8 be_quiet;
 
-u8 *stdin_file,                        /* stdin file                        */
-    *in_dir,                           /* input folder                      */
+char*stdin_file;                       /* stdin file                        */
+
+u8  *in_dir,                           /* input folder                      */
     *doc_path,                         /* Path to docs                      */
         *at_file = NULL;               /* Substitution string for @@        */
 
@@ -702,16 +703,19 @@ static void find_binary(afl_forkserver_t* fsrv, u8* fname) {
 
 /* Main entry point */
 
-int main(int argc, char** argv, char** envp) {
+int main(int argc, char** argv_orig, char** envp) {
 
   // TODO: u64 mem_limit = MEM_LIMIT;                  /* Memory limit (MB) */
 
   s32    opt, i;
   u8     mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0;
   u32    tcnt = 0;
-  char** use_argv;
+  char **use_argv;
+
+  char **argv = argv_cpy_dup(argc, argv_orig);
 
-  afl_forkserver_t* fsrv = calloc(1, sizeof(afl_forkserver_t));
+  afl_forkserver_t fsrv_var = {0};
+  afl_forkserver_t* fsrv = &fsrv_var;
   afl_fsrv_init(fsrv);
 
   doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
@@ -957,7 +961,12 @@ int main(int argc, char** argv, char** envp) {
     fsrv->out_fd = open(stdin_file, O_RDWR | O_CREAT | O_EXCL, 0600);
     if (fsrv->out_fd < 0) PFATAL("Unable to create '%s'", fsrv->out_file);
 
-    if (arg_offset) argv[arg_offset] = stdin_file;
+    if (arg_offset && argv[arg_offset] != stdin_file) {
+      
+      ck_free(argv[arg_offset]);
+      argv[arg_offset] = strdup(stdin_file);
+
+    }
 
     if (get_afl_env("AFL_DEBUG")) {
 
@@ -1024,7 +1033,7 @@ int main(int argc, char** argv, char** envp) {
   if (stdin_file) {
 
     unlink(stdin_file);
-    free(stdin_file);
+    ck_free(stdin_file);
     stdin_file = NULL;
 
   }
@@ -1033,12 +1042,13 @@ int main(int argc, char** argv, char** envp) {
 
   u32 ret = child_crashed * 2 + fsrv->child_timed_out;
 
-  if (fsrv->target_path) free(fsrv->target_path);
+  if (fsrv->target_path) ck_free(fsrv->target_path);
 
   afl_fsrv_deinit(fsrv);
-  free(fsrv);
   if (stdin_file) ck_free(stdin_file);
 
+  argv_cpy_free(argv);
+
   exit(ret);
 
 }
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 5a29bec1..5d5ea477 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -1096,13 +1096,16 @@ static void read_bitmap(u8* fname) {
 
 /* Main entry point */
 
-int main(int argc, char** argv, char** envp) {
+int main(int argc, char** argv_orig, char** envp) {
 
   s32    opt;
   u8     mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0;
-  char** use_argv;
+  char **use_argv;
 
-  afl_forkserver_t* fsrv = calloc(1, sizeof(afl_forkserver_t));
+  char **argv = argv_cpy_dup(argc, argv_orig);
+
+  afl_forkserver_t fsrv_var = {0};
+  afl_forkserver_t* fsrv = &fsrv_var;
   afl_fsrv_init(fsrv);
 
   doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
@@ -1354,11 +1357,11 @@ int main(int argc, char** argv, char** envp) {
   afl_shm_deinit(&shm);
   afl_fsrv_deinit(fsrv);
   if (fsrv->target_path) ck_free(fsrv->target_path);
-  ck_free(fsrv);
-  fsrv = NULL;
   if (mask_bitmap) ck_free(mask_bitmap);
   if (in_data) ck_free(in_data);
 
+  argv_cpy_free(argv);
+
   exit(0);
 
 }