Skip to content
This repository was archived by the owner on Nov 1, 2023. It is now read-only.

Commit b45446a

Browse files
authored
Make crashdumps optional in config (#3409)
1 parent 9420f51 commit b45446a

File tree

5 files changed

+101
-70
lines changed

5 files changed

+101
-70
lines changed

src/ApiService/ApiService/onefuzzlib/Defs.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ public static class Defs {
192192
),
193193
new ContainerDefinition(
194194
Type:ContainerType.Crashdumps,
195-
Compare: Compare.Equal,
195+
Compare: Compare.AtMost,
196196
Value:1,
197197
Permissions: ContainerPermission.Write
198198
),
@@ -287,7 +287,7 @@ public static class Defs {
287287
),
288288
new ContainerDefinition(
289289
Type:ContainerType.Crashdumps,
290-
Compare: Compare.Equal,
290+
Compare: Compare.AtMost,
291291
Value:1,
292292
Permissions: ContainerPermission.Write
293293
),

src/agent/onefuzz-task/src/local/libfuzzer_fuzz.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub fn build_fuzz_config(
5151
inputs,
5252
readonly_inputs,
5353
crashes,
54-
crashdumps,
54+
crashdumps: Some(crashdumps),
5555
target_exe,
5656
target_env,
5757
target_options,

src/agent/onefuzz-task/src/local/template.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,9 @@ impl TaskConfig {
144144
inputs: context.to_monitored_sync_dir("inputs", &config.inputs)?,
145145
readonly_inputs: Some(ri?),
146146
crashes: context.to_monitored_sync_dir("crashes", &config.crashes)?,
147-
crashdumps: context.to_monitored_sync_dir("crashdumps", &config.crashdumps)?,
147+
crashdumps: Some(
148+
context.to_monitored_sync_dir("crashdumps", &config.crashdumps)?,
149+
),
148150
target_exe: config.target_exe.clone(),
149151
target_env: config.target_env.clone(),
150152
target_options: config.target_options.clone(),

src/agent/onefuzz-task/src/tasks/fuzz/libfuzzer/common.rs

Lines changed: 65 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ pub struct Config<L: LibFuzzerType + Send + Sync + ?Sized> {
7474
pub inputs: SyncedDir,
7575
pub readonly_inputs: Option<Vec<SyncedDir>>,
7676
pub crashes: SyncedDir,
77-
pub crashdumps: SyncedDir,
77+
pub crashdumps: Option<SyncedDir>,
7878
pub target_exe: PathBuf,
7979
pub target_env: HashMap<String, String>,
8080
pub target_options: Vec<String>,
@@ -131,7 +131,13 @@ where
131131
let resync = self.continuous_sync_inputs();
132132
let new_inputs = self.config.inputs.monitor_results(new_coverage, true);
133133
let new_crashes = self.config.crashes.monitor_results(new_result, true);
134-
let new_crashdumps = self.config.crashdumps.monitor_results(new_crashdump, true);
134+
let new_crashdumps = async {
135+
if let Some(crashdumps) = &self.config.crashdumps {
136+
crashdumps.monitor_results(new_crashdump, true).await
137+
} else {
138+
Ok(())
139+
}
140+
};
135141

136142
let (stats_sender, stats_receiver) = mpsc::unbounded_channel();
137143
let report_stats = report_runtime_stats(stats_receiver, hb_client);
@@ -350,64 +356,66 @@ where
350356
}
351357
}
352358

353-
// check for core dumps on Linux:
354-
// note that collecting the dumps must be enabled by the template
355-
#[cfg(target_os = "linux")]
356-
if let Some(pid) = pid {
357-
// expect crash dump to exist in CWD
358-
let filename = format!("core.{pid}");
359-
let dest_filename = dump_file_name.as_deref().unwrap_or(OsStr::new(&filename));
360-
let dest_path = self.config.crashdumps.local_path.join(dest_filename);
361-
match tokio::fs::rename(&filename, &dest_path).await {
362-
Ok(()) => {
363-
info!(
364-
"moved crash dump {} to output directory: {}",
365-
filename,
366-
dest_path.display()
367-
);
368-
}
369-
Err(e) => {
370-
if e.kind() == std::io::ErrorKind::NotFound {
371-
// okay, no crash dump found
372-
info!("no crash dump found with name: {}", filename);
373-
} else {
374-
return Err(e).context("moving crash dump to output directory");
359+
if let Some(crashdumps) = &self.config.crashdumps {
360+
// check for core dumps on Linux:
361+
// note that collecting the dumps must be enabled by the template
362+
#[cfg(target_os = "linux")]
363+
if let Some(pid) = pid {
364+
// expect crash dump to exist in CWD
365+
let filename = format!("core.{pid}");
366+
let dest_filename = dump_file_name.as_deref().unwrap_or(OsStr::new(&filename));
367+
let dest_path = crashdumps.local_path.join(dest_filename);
368+
match tokio::fs::rename(&filename, &dest_path).await {
369+
Ok(()) => {
370+
info!(
371+
"moved crash dump {} to output directory: {}",
372+
filename,
373+
dest_path.display()
374+
);
375+
}
376+
Err(e) => {
377+
if e.kind() == std::io::ErrorKind::NotFound {
378+
// okay, no crash dump found
379+
info!("no crash dump found with name: {}", filename);
380+
} else {
381+
return Err(e).context("moving crash dump to output directory");
382+
}
375383
}
376384
}
385+
} else {
386+
warn!("no PID found for libfuzzer process");
377387
}
378-
} else {
379-
warn!("no PID found for libfuzzer process");
380-
}
381388

382-
// check for crash dumps on Windows:
383-
#[cfg(target_os = "windows")]
384-
{
385-
let dumpfile_extension = Some(std::ffi::OsStr::new("dmp"));
386-
387-
let mut working_dir = tokio::fs::read_dir(".").await?;
388-
let mut found_dump = false;
389-
while let Some(next) = working_dir.next_entry().await? {
390-
if next.path().extension() == dumpfile_extension {
391-
// Windows dumps get a fixed filename so we will generate a random one,
392-
// if there's no valid target crash name:
393-
let dest_filename =
394-
dump_file_name.unwrap_or_else(|| uuid::Uuid::new_v4().to_string().into());
395-
let dest_path = self.config.crashdumps.local_path.join(&dest_filename);
396-
tokio::fs::rename(next.path(), &dest_path)
397-
.await
398-
.context("moving crash dump to output directory")?;
399-
info!(
400-
"moved crash dump {} to output directory: {}",
401-
next.path().display(),
402-
dest_path.display()
403-
);
404-
found_dump = true;
405-
break;
389+
// check for crash dumps on Windows:
390+
#[cfg(target_os = "windows")]
391+
{
392+
let dumpfile_extension = Some(std::ffi::OsStr::new("dmp"));
393+
394+
let mut working_dir = tokio::fs::read_dir(".").await?;
395+
let mut found_dump = false;
396+
while let Some(next) = working_dir.next_entry().await? {
397+
if next.path().extension() == dumpfile_extension {
398+
// Windows dumps get a fixed filename so we will generate a random one,
399+
// if there's no valid target crash name:
400+
let dest_filename = dump_file_name
401+
.unwrap_or_else(|| uuid::Uuid::new_v4().to_string().into());
402+
let dest_path = crashdumps.local_path.join(&dest_filename);
403+
tokio::fs::rename(next.path(), &dest_path)
404+
.await
405+
.context("moving crash dump to output directory")?;
406+
info!(
407+
"moved crash dump {} to output directory: {}",
408+
next.path().display(),
409+
dest_path.display()
410+
);
411+
found_dump = true;
412+
break;
413+
}
406414
}
407-
}
408415

409-
if !found_dump {
410-
info!("no crash dump found with extension .dmp");
416+
if !found_dump {
417+
info!("no crash dump found with extension .dmp");
418+
}
411419
}
412420
}
413421

@@ -425,7 +433,9 @@ where
425433

426434
// output directories (init):
427435
self.config.crashes.init().await?;
428-
self.config.crashdumps.init().await?;
436+
if let Some(crashdumps) = &self.config.crashdumps {
437+
crashdumps.init().await?;
438+
}
429439

430440
Ok(())
431441
}

src/agent/onefuzz-task/src/tasks/fuzz/supervisor.rs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ use futures::TryFutureExt;
4141
pub struct SupervisorConfig {
4242
pub inputs: SyncedDir,
4343
pub crashes: SyncedDir,
44-
pub crashdumps: SyncedDir,
44+
pub crashdumps: Option<SyncedDir>,
4545
pub supervisor_exe: String,
4646
pub supervisor_env: HashMap<String, String>,
4747
pub supervisor_options: Vec<String>,
@@ -82,12 +82,29 @@ pub async fn spawn(config: SupervisorConfig) -> Result<(), Error> {
8282
let monitor_crashes = crashes.monitor_results(new_result, false);
8383

8484
// setup crashdumps
85-
let crashdumps = SyncedDir {
86-
local_path: runtime_dir.path().join("crashdumps"),
87-
remote_path: config.crashdumps.remote_path.clone(),
85+
let (crashdump_dir, monitor_crashdumps) = {
86+
let crashdump_dir = if let Some(crashdumps) = &config.crashdumps {
87+
let dir = SyncedDir {
88+
local_path: runtime_dir.path().join("crashdumps"),
89+
remote_path: crashdumps.remote_path.clone(),
90+
};
91+
dir.init().await?;
92+
Some(dir)
93+
} else {
94+
None
95+
};
96+
97+
let monitor_dir = crashdump_dir.clone();
98+
let monitor_crashdumps = async move {
99+
if let Some(crashdumps) = monitor_dir {
100+
crashdumps.monitor_results(new_crashdump, false).await
101+
} else {
102+
Ok(())
103+
}
104+
};
105+
106+
(crashdump_dir, monitor_crashdumps)
88107
};
89-
crashdumps.init().await?;
90-
let monitor_crashdumps = crashdumps.monitor_results(new_crashdump, false);
91108

92109
// setup coverage
93110
if let Some(coverage) = &config.coverage {
@@ -148,7 +165,7 @@ pub async fn spawn(config: SupervisorConfig) -> Result<(), Error> {
148165
&runtime_dir.path(),
149166
&config,
150167
&crashes,
151-
&crashdumps,
168+
crashdump_dir.as_ref(),
152169
&inputs,
153170
reports_dir.path().to_path_buf(),
154171
)
@@ -217,7 +234,7 @@ async fn start_supervisor(
217234
runtime_dir: impl AsRef<Path>,
218235
config: &SupervisorConfig,
219236
crashes: &SyncedDir,
220-
crashdumps: &SyncedDir,
237+
crashdumps: Option<&SyncedDir>,
221238
inputs: &SyncedDir,
222239
reports_dir: PathBuf,
223240
) -> Result<Child> {
@@ -233,7 +250,9 @@ async fn start_supervisor(
233250
.supervisor_options(&config.supervisor_options)
234251
.runtime_dir(&runtime_dir)
235252
.crashes(&crashes.local_path)
236-
.crashdumps(&crashdumps.local_path)
253+
.set_optional_ref(&crashdumps, |expand, crashdumps| {
254+
expand.crashdumps(&crashdumps.local_path)
255+
})
237256
.input_corpus(&inputs.local_path)
238257
.reports_dir(reports_dir)
239258
.setup_dir(&config.common.setup_dir)
@@ -410,7 +429,7 @@ mod tests {
410429
target_options,
411430
inputs: corpus_dir.clone(),
412431
crashes: crashes.clone(),
413-
crashdumps: crashdumps.clone(),
432+
crashdumps: Some(crashdumps.clone()),
414433
tools: None,
415434
wait_for_files: None,
416435
stats_file: None,
@@ -447,7 +466,7 @@ mod tests {
447466
runtime_dir,
448467
&config,
449468
&crashes,
450-
&crashdumps,
469+
Some(&crashdumps),
451470
&corpus_dir,
452471
reports_dir,
453472
)

0 commit comments

Comments
 (0)