From b519d249817742cc64027bfbfd09c11350d879a3 Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 7 Apr 2023 09:36:08 +0900 Subject: [PATCH] Fix Testcase renaming on disk (#1191) * fix set_filename * use ? quantifier instead of expect * fix clippy * cargo fmt * add rename old file to new file logic * add cfg feature std * add no_std set_filename * fix create and remove lockfile logic * fix cargo fmt * remove unused import * cargo fmt * fix clippy * fix lock filecondition * remove useless import * fix path * revert fuzzer Makefile.toml * fix fmt --------- Co-authored-by: Dominik Maier Co-authored-by: Dongjia "toka" Zhang --- libafl/src/corpus/inmemory_ondisk.rs | 11 ++++--- libafl/src/corpus/testcase.rs | 49 +++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/libafl/src/corpus/inmemory_ondisk.rs b/libafl/src/corpus/inmemory_ondisk.rs index d70fe2eb19..6809e959e9 100644 --- a/libafl/src/corpus/inmemory_ondisk.rs +++ b/libafl/src/corpus/inmemory_ondisk.rs @@ -221,7 +221,6 @@ where let mut ctr = 2; let filename = loop { let lockfile = format!(".{file}.lafl_lock"); - // try to create lockfile. if OpenOptions::new() .write(true) @@ -229,15 +228,19 @@ where .open(self.dir_path.join(lockfile)) .is_ok() { - break self.dir_path.join(file); + break file; } file = format!("{file_orig}-{ctr}"); ctr += 1; }; - let filename_str = filename.to_str().expect("Invalid Path"); - testcase.set_filename(filename_str.into()); + let file_path = self.dir_path.join(filename.clone()); + let filename_str = file_path.to_str().expect("Invalid Path"); + testcase.set_filename(filename_str.into())?; + + let lock_file_path = self.dir_path.join(format!(".{filename}.lafl_lock")); + fs::remove_file(lock_file_path)?; }; if self.meta_format.is_some() { let mut filename = PathBuf::from(testcase.filename().as_ref().unwrap()); diff --git a/libafl/src/corpus/testcase.rs b/libafl/src/corpus/testcase.rs index 16d62fbbfd..5f5ee25767 100644 --- a/libafl/src/corpus/testcase.rs +++ b/libafl/src/corpus/testcase.rs @@ -8,6 +8,8 @@ use core::{ option::Option, time::Duration, }; +#[cfg(feature = "std")] +use std::fs; use serde::{Deserialize, Serialize}; @@ -144,8 +146,53 @@ where /// Set the filename #[inline] - pub fn set_filename(&mut self, filename: String) { + #[cfg(feature = "std")] + pub fn set_filename(&mut self, filename: String) -> Result<(), Error> { + use std::fs::OpenOptions; + + if self.filename.is_some() { + let f = self.filename.clone().unwrap(); + let old_filename = f.as_str(); + + let new_filename = filename.as_str(); + + // Do operations below when new filename is specified + if old_filename.eq(new_filename) { + return Ok(()); + } + + let new_lock_filename = format!(".{new_filename}.lafl_lock"); + + // Try to create lock file for new testcases + if OpenOptions::new() + .create(true) + .write(true) + .open(&new_lock_filename) + .is_err() + { + return Err(Error::illegal_state( + "unable to create lock file for new testcase", + )); + } + + fs::rename(old_filename, new_filename)?; + + let old_metadata_filename = format!(".{old_filename}.metadata"); + let new_metadata_filename = format!(".{new_filename}.metadata"); + fs::rename(old_metadata_filename, new_metadata_filename)?; + + fs::remove_file(&new_lock_filename)?; + } + self.filename = Some(filename); + Ok(()) + } + + #[inline] + #[cfg(feature = "no_std")] + pub fn set_filename(&mut self, filename: String) -> Result<(), Error> { + self.filename = Some(filename); + Ok(()) } /// Get the execution time of the testcase