(
&self,
run_exploit: bool,
time_limit: Option<u64>,
min_corpus: Option<bool>,
)
| 776 | } |
| 777 | |
| 778 | pub fn run_libfuzzer( |
| 779 | &self, |
| 780 | run_exploit: bool, |
| 781 | time_limit: Option<u64>, |
| 782 | min_corpus: Option<bool>, |
| 783 | ) -> Result<()> { |
| 784 | let fuzzer_dir = if run_exploit { |
| 785 | self.deopt.get_library_fuzzer_dir(true)? |
| 786 | } else { |
| 787 | self.deopt.get_library_fuzzer_dir(false)? |
| 788 | }; |
| 789 | let time_limit = if let Some(limit) = time_limit { |
| 790 | if limit == 0 { |
| 791 | u64::MAX |
| 792 | } else { |
| 793 | limit |
| 794 | } |
| 795 | } else { |
| 796 | 60 * 60 * 24 |
| 797 | }; |
| 798 | let should_minimize = min_corpus.unwrap_or(true); |
| 799 | |
| 800 | if !fuzzer_dir.is_dir() { |
| 801 | eyre::bail!("Fuzzer_dir {fuzzer_dir:?} should be a dir") |
| 802 | } |
| 803 | |
| 804 | let mut childs = Vec::new(); |
| 805 | for path in crate::deopt::utils::read_sort_dir(&fuzzer_dir)? { |
| 806 | if !path.is_dir() { |
| 807 | continue; |
| 808 | } |
| 809 | let fuzzer_binary: PathBuf = [path.clone(), "fuzzer".into()].iter().collect(); |
| 810 | let corpus: PathBuf = [path.clone(), "corpus".into()].iter().collect(); |
| 811 | let minimize: PathBuf = [path.clone(), "minimized".into()].iter().collect(); |
| 812 | let final_corpus: PathBuf = [path.clone(), "minimized_corpus".into()].iter().collect(); |
| 813 | if final_corpus.exists() { |
| 814 | std::fs::rename(final_corpus, &corpus)?; |
| 815 | } |
| 816 | if should_minimize { |
| 817 | self.minimize_corpus_by_efficient_sancov(&fuzzer_binary, &minimize, &corpus)?; |
| 818 | std::fs::remove_dir_all(&corpus)?; |
| 819 | std::fs::rename(minimize, &corpus)?; |
| 820 | } |
| 821 | |
| 822 | let child = self.spawn_libfuzzer(&fuzzer_binary, &corpus)?; |
| 823 | childs.push((child, path)); |
| 824 | } |
| 825 | let start = std::time::Instant::now(); |
| 826 | |
| 827 | loop { |
| 828 | for (child, path) in childs.iter_mut() { |
| 829 | match child.try_wait() { |
| 830 | Ok(Some(_status)) => { |
| 831 | let new_child = respawn_libfuzzer_process(path, self)?; |
| 832 | _ = std::mem::replace(child, new_child); |
| 833 | } |
| 834 | Ok(None) => { |
| 835 | log::debug!("{path:?} running."); |
no test coverage detected