about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDominik Maier <d.maier@avm.de>2020-03-09 19:27:22 +0100
committerDominik Maier <domenukk@gmail.com>2020-03-09 19:30:26 +0100
commit782cffb13054e13fc6e987cda626fa475468453c (patch)
tree23fc8bc94875e7b36fee94092e71467eca2f26e0
parenta24352ddfd16c151df48b4a0cf89ced587165f1e (diff)
downloadafl++-782cffb13054e13fc6e987cda626fa475468453c.tar.gz
fixed numerous leaks
-rw-r--r--src/afl-common.c98
-rw-r--r--src/afl-fuzz-init.c4
-rw-r--r--src/afl-fuzz-mutators.c4
-rw-r--r--src/afl-showmap.c33
-rw-r--r--src/afl-tmin.c6
5 files changed, 123 insertions, 22 deletions
diff --git a/src/afl-common.c b/src/afl-common.c
index 06c691b3..f175f604 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -50,11 +50,86 @@ void detect_file_args(char** argv, u8* prog_in, u8 use_stdin) {
   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. */
+
+        // TODO: n_arg is never freed
+
+        *aa_loc = 0;
+        n_arg = alloc_printf("%s%s%s", argv[i], aa_subst, aa_loc + 2);
+        argv[i] = n_arg;
+        *aa_loc = '@';
+
+        if (prog_in[0] != '/') ck_free(aa_subst);
+
+      }
+
+    }
+
+    i++;
+
+  }
+
+  ck_free(cwd);                                                 /* not tracked */
+
+}
+
+
+char **create_file_args(int argc, char** argv, u8* prog_in, u8 use_stdin) {
+
+  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");
 
   }
 
@@ -91,23 +166,42 @@ void detect_file_args(char** argv, u8* prog_in, u8 use_stdin) {
 
         *aa_loc = 0;
         n_arg = alloc_printf("%s%s%s", argv[i], aa_subst, aa_loc + 2);
-        argv[i] = n_arg;
+        ret[i] = n_arg;
         *aa_loc = '@';
 
         if (prog_in[0] != '/') ck_free(aa_subst);
 
+        i++;
+        continue;
+
       }
 
     }
 
+    ret[i] = ck_strdup(argv[i]);
     i++;
 
   }
+  ret[i] = NULL;
 
-  free(cwd);                                                 /* not tracked */
+  ck_free(cwd);                                                 /* not tracked */
 
+  return ret;
 }
 
+/* frees all args in the given argv, 
+   previously created by create_file_args */
+void destroy_file_args(char **argv) {
+
+  u32 i=0;
+  while(argv[i]) {
+    ck_free(argv[i]);
+    i++;
+  }
+  ck_free(argv);
+}
+
+
 /* Rewrite argv for QEMU. */
 
 char** get_qemu_argv(u8* own_loc, u8** target_path_p, int argc, char** argv) {
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 427cea04..c01bf4d4 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -373,7 +373,7 @@ void read_testcases(afl_state_t* afl) {
 
     u8 passed_det = 0;
 
-    free(nl[i]);                                             /* not tracked */
+    ck_free(nl[i]);                                             /* not tracked */
 
     if (lstat(fn2, &st) || access(fn2, R_OK))
       PFATAL("Unable to access '%s'", fn2);
@@ -404,7 +404,7 @@ void read_testcases(afl_state_t* afl) {
 
   }
 
-  free(nl);                                                  /* not tracked */
+  ck_free(nl);                                                /* not tracked */
 
   if (!afl->queued_paths) {
 
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index 0edd93a0..02d7661e 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -233,7 +233,7 @@ u8 trim_case_custom(afl_state_t* afl, struct queue_entry* q, u8* in_buf) {
 
     if (afl->stop_soon || fault == FAULT_ERROR) {
 
-      free(retbuf);
+      ck_free(retbuf);
       goto abort_trimming;
 
     }
@@ -272,7 +272,7 @@ u8 trim_case_custom(afl_state_t* afl, struct queue_entry* q, u8* in_buf) {
 
     }
 
-    free(retbuf);
+    ck_free(retbuf);
 
     /* Since this can be slow, update the screen every now and then. */
 
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 90161bb3..26f166a5 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -146,7 +146,7 @@ static void at_exit_handler(void) {
 
 /* Write results. */
 
-static u32 write_results_to_file(afl_forkserver_t* fsrv) {
+static u32 write_results_to_file(afl_forkserver_t* fsrv, u8 *outfile) {
 
   s32 fd;
   u32 i, ret = 0;
@@ -154,21 +154,21 @@ static u32 write_results_to_file(afl_forkserver_t* fsrv) {
   u8 cco = !!getenv("AFL_CMIN_CRASHES_ONLY"),
      caa = !!getenv("AFL_CMIN_ALLOW_ANY");
 
-  if (!strncmp(fsrv->out_file, "/dev/", 5)) {
+  if (!strncmp(outfile, "/dev/", 5)) {
 
-    fd = open(fsrv->out_file, O_WRONLY, 0600);
+    fd = open(outfile, O_WRONLY, 0600);
     if (fd < 0) PFATAL("Unable to open '%s'", fsrv->out_file);
 
-  } else if (!strcmp(fsrv->out_file, "-")) {
+  } else if (!strcmp(outfile, "-")) {
 
     fd = dup(1);
     if (fd < 0) PFATAL("Unable to open stdout");
 
   } else {
 
-    unlink(fsrv->out_file);                                /* Ignore errors */
-    fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
-    if (fd < 0) PFATAL("Unable to create '%s'", fsrv->out_file);
+    unlink(outfile);                                /* Ignore errors */
+    fd = open(outfile, O_WRONLY | O_CREAT | O_EXCL, 0600);
+    if (fd < 0) PFATAL("Unable to create '%s'", outfile);
 
   }
 
@@ -177,7 +177,7 @@ static u32 write_results_to_file(afl_forkserver_t* fsrv) {
     for (i = 0; i < MAP_SIZE; i++)
       if (fsrv->trace_bits[i]) ret++;
 
-    ck_write(fd, fsrv->trace_bits, MAP_SIZE, fsrv->out_file);
+    ck_write(fd, fsrv->trace_bits, MAP_SIZE, outfile);
     close(fd);
 
   } else {
@@ -219,7 +219,7 @@ static u32 write_results_to_file(afl_forkserver_t* fsrv) {
 
 static u32 write_results(afl_forkserver_t* fsrv) {
 
-  return write_results_to_file(fsrv);
+  return write_results_to_file(fsrv, fsrv->out_file);
 
 }
 
@@ -494,8 +494,6 @@ static void run_target(afl_forkserver_t* fsrv, char** argv) {
 
 }
 
-extern afl_forkserver_t* fsrv_glob;
-
 /* Handle Ctrl-C and the like. */
 
 static void handle_stop_sig(int sig) {
@@ -997,7 +995,7 @@ int main(int argc, char** argv, char** envp) {
 
         run_target_forkserver(fsrv, use_argv, in_data, in_len);
         ck_free(in_data);
-        tcnt = write_results_to_file(fsrv);
+        tcnt = write_results_to_file(fsrv, outfile);
 
       }
 
@@ -1005,6 +1003,9 @@ int main(int argc, char** argv, char** envp) {
 
     if (!quiet_mode) OKF("Processed %u input files.", total_execs);
 
+    closedir(dir_in);
+    closedir(dir_out);
+
   } else {
 
     run_target(fsrv, use_argv);
@@ -1023,18 +1024,22 @@ int main(int argc, char** argv, char** envp) {
   if (stdin_file) {
 
     unlink(stdin_file);
+    free(stdin_file);
     stdin_file = NULL;
 
   }
 
   afl_shm_deinit(&shm);
 
-  u8 child_timed_out = fsrv->child_timed_out;
+  u32 ret = child_crashed * 2 + fsrv->child_timed_out;
+
+  if (fsrv->target_path) free(fsrv->target_path);
+
   afl_fsrv_deinit(fsrv);
   free(fsrv);
   if (stdin_file) ck_free(stdin_file);
 
-  exit(child_crashed * 2 + child_timed_out);
+  exit(ret);
 
 }
 
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 84e69184..df8d289f 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -1344,6 +1344,7 @@ int main(int argc, char** argv, char** envp) {
   ACTF("Writing output to '%s'...", output_file);
 
   unlink(fsrv->out_file);
+  if (fsrv->out_file) ck_free(fsrv->out_file);
   fsrv->out_file = NULL;
 
   close(write_to_file(output_file, in_data, in_len));
@@ -1352,8 +1353,9 @@ int main(int argc, char** argv, char** envp) {
 
   afl_shm_deinit(&shm);
   afl_fsrv_deinit(fsrv);
-  if (fsrv->out_file) ck_free(fsrv->out_file);
-  free(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);