about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorcoco <cornelius@hexgolems.com>2023-10-04 12:29:41 -0700
committercoco <cornelius@hexgolems.com>2023-10-04 12:44:56 -0700
commitc622e4c5652b8a3dca8ad057d8c5c2130f735867 (patch)
tree60558475428a19a076d0a10ea99076a72ac4fff7 /src
parent17bfb3a4084dd3e24d8521cedc6a50ecba43cd6f (diff)
downloadafl++-c622e4c5652b8a3dca8ad057d8c5c2130f735867.tar.gz
Make fuzzer_stats update atomic
This writes fuzzer_stats to a temp file and then atomically renames the
temp file into fuzzer_stats so that any read on fuzzer_stats will always
return a consistent view of the AFL state (otherwise there is a very
low change of AFL's write and $tool's reads to race and yield
inconsistent results).
Diffstat (limited to 'src')
-rw-r--r--src/afl-fuzz-stats.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 81628a86..66e32e78 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -250,11 +250,13 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
 #endif
 
   u64   cur_time = get_cur_time();
-  u8    fn[PATH_MAX];
+  u8    fn_tmp[PATH_MAX];
+  u8    fn_final[PATH_MAX];
   FILE *f;
 
-  snprintf(fn, PATH_MAX, "%s/fuzzer_stats", afl->out_dir);
-  f = create_ffile(fn);
+  snprintf(fn_tmp, PATH_MAX, "%s/.fuzzer_stats_tmp", afl->out_dir);
+  snprintf(fn_final, PATH_MAX, "%s/fuzzer_stats", afl->out_dir);
+  f = create_ffile(fn_tmp);
 
   /* Keep last values in case we're called from another context
      where exec/sec stats and such are not readily available. */
@@ -412,6 +414,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
   }
 
   fclose(f);
+  rename(fn_tmp, fn_final);
 
 }