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

Capture crash dumps from libfuzzer, when provided #2793

Merged
merged 80 commits into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
fa6737f
WIP
Porges Feb 2, 2023
ecd1c78
Fix test
Porges Feb 2, 2023
6e5800d
Update docs
Porges Feb 2, 2023
3c95ed7
Server side changes
Porges Feb 2, 2023
3a9b160
Doh
Porges Feb 3, 2023
0d37c41
Update integration tests
Porges Feb 3, 2023
96a1ced
WIP
Porges Feb 3, 2023
8b848c0
Merge branch 'main' into asan_dumps
Porges Feb 6, 2023
9c6485d
Include Crashdumps container in BuildTaskConfig
Porges Feb 6, 2023
217a667
Add target_env support to AFL template
Porges Feb 6, 2023
fcd508c
Merge branch 'main' into asan_dumps
Porges Feb 7, 2023
c053d79
Merge branch 'main' into asan_dumps
Porges Feb 13, 2023
413c3ea
Merge branch 'main' into asan_dumps
Porges Feb 15, 2023
977d9d2
Merge remote-tracking branch 'origin/main' into HEAD
Porges Feb 19, 2023
fbcdde4
Add support to generic supervisor
Porges Feb 15, 2023
7002cea
Fixup
Porges Feb 19, 2023
f09666b
Merge branch 'main' into asan_dumps
Porges Feb 20, 2023
6bcbb9d
Add monitor_results for crashdumps
Porges Feb 20, 2023
003d0d5
Update run.sh
Porges Feb 20, 2023
b17a3c7
Merge branch 'main' into asan_dumps
Porges Feb 20, 2023
3277147
Remove changes from setup.sh
Porges Feb 20, 2023
6d5bee4
Thinko
Porges Feb 21, 2023
4698485
Add unmap_shadow_on_exit
Porges Feb 21, 2023
235fb1e
Merge branch 'main' into asan_dumps
Porges Feb 22, 2023
55e8921
Merge branch 'main' into asan_dumps
Porges Feb 26, 2023
cc82b2c
Merge branch 'main' into asan_dumps
Porges Feb 27, 2023
939b056
Merge remote-tracking branch 'origin/main' into asan_dumps
Porges Mar 20, 2023
3382270
Windows impl
Porges Mar 20, 2023
23e5b59
Fix Windows build
Porges Mar 21, 2023
f1544d9
Merge branch 'main' into asan_dumps
Porges Mar 22, 2023
10fdd5d
Merge branch 'main' into asan_dumps
Porges Mar 28, 2023
fa626bd
Make Windows wait for dump
Porges Mar 28, 2023
61002af
Merge branch 'main' into asan_dumps
Porges Apr 2, 2023
8a4de92
Merge branch 'main' into asan_dumps
Porges Apr 4, 2023
5ca1617
Merge branch 'main' into asan_dumps
Porges Apr 4, 2023
5a4929e
Merge branch 'main' into asan_dumps
Porges Apr 25, 2023
850102b
Merge branch 'main' into asan_dumps
Porges Apr 25, 2023
ad7f488
Merge branch 'main' into asan_dumps
Porges Apr 28, 2023
70d6e9d
Merge remote-tracking branch 'origin/main' into asan_dumps
Porges May 8, 2023
b895abd
Merge remote-tracking branch 'origin/main' into asan_dumps
Porges May 14, 2023
319e443
Correct Windows dump parameter in integration test
Porges May 14, 2023
6e165f8
Remove leading dot of extension
Porges May 15, 2023
719f948
Improve integration test logs
Porges May 15, 2023
473bb08
Merge branch 'main' into asan_dumps
Porges May 16, 2023
a143532
...
Porges May 15, 2023
5352b48
Expand valid scaleset names (#3045)
Porges May 16, 2023
2c57f27
Increase lock wait timeout for qemu_user setup (#3114)
Porges May 17, 2023
f862b3f
Merge remote-tracking branch 'origin/main' into asan_dumps
Porges May 21, 2023
5de3502
Remove unused import
Porges May 21, 2023
024bdb5
Merge branch 'main' into asan_dumps
Porges May 25, 2023
e57eba6
Merge remote-tracking branch 'origin/main' into asan_dumps
Porges Jun 6, 2023
4ab6737
add comment
Porges Jun 6, 2023
b27fd3e
Merge branch 'main' into asan_dumps
Porges Jun 27, 2023
b88dbc1
post-merge fix
Porges Jun 27, 2023
e09e815
Rename crashdumps appropriately
Porges Jun 27, 2023
70e9b6e
Restrict failure types during test
Porges Jun 27, 2023
b3d8e11
Merge branch 'main' into asan_dumps
Porges Jul 3, 2023
007b28d
add more logging
Porges Jul 3, 2023
832798a
more logging
Porges Jul 4, 2023
51118d0
Yet more logging
Porges Jul 4, 2023
9c2e77d
logging again
Porges Jul 4, 2023
af528a8
Fix path concatenation
Porges Jul 4, 2023
0cacbe5
Merge branch 'main' into asan_dumps
Porges Jul 5, 2023
6e46588
Merge branch 'main' into asan_dumps
Porges Jul 5, 2023
04a7b92
Merge branch 'main' into asan_dumps
Porges Jul 11, 2023
c194887
Try removing "workaround"
Porges Jul 11, 2023
4a8364e
Update cache keys
Porges Jul 11, 2023
2e319fb
Compile libfuzzer test using cl.exe
Porges Jul 11, 2023
5e57ebf
Change pinned commit
Porges Jul 11, 2023
93f850b
Bump Windows image version
Porges Jul 11, 2023
9cbc116
Update Makefile again
Porges Jul 11, 2023
338f38c
Merge branch 'main' into asan_dumps
Porges Jul 12, 2023
d32c8a0
Merge branch 'main' into asan_dumps
Porges Jul 18, 2023
31bf877
Merge branch 'main' into asan_dumps
Porges Aug 1, 2023
f65c2b6
Post-merge update
Porges Aug 1, 2023
bf2fe3a
Disable crashdump check for Linux in test
Porges Aug 1, 2023
7ada9ac
Merge branch 'main' into asan_dumps
Porges Aug 1, 2023
6906dc2
Merge branch 'main' into asan_dumps
Porges Aug 8, 2023
919ffbf
Produce message when no crash dump was found
Porges Aug 8, 2023
09a7ec8
Merge branch 'main' into asan_dumps
Porges Aug 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/webhook_events.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ If webhook is set to have Event Grid message format then the payload will look a
"coverage",
"crashes",
"inputs",
"crashdumps",
"no_repro",
"readonly_inputs",
"reports",
Expand Down Expand Up @@ -1983,6 +1984,7 @@ If webhook is set to have Event Grid message format then the payload will look a
"coverage",
"crashes",
"inputs",
"crashdumps",
"no_repro",
"readonly_inputs",
"reports",
Expand Down Expand Up @@ -2899,6 +2901,7 @@ If webhook is set to have Event Grid message format then the payload will look a
"coverage",
"crashes",
"inputs",
"crashdumps",
"no_repro",
"readonly_inputs",
"reports",
Expand Down Expand Up @@ -3370,6 +3373,7 @@ If webhook is set to have Event Grid message format then the payload will look a
"coverage",
"crashes",
"inputs",
"crashdumps",
"no_repro",
"readonly_inputs",
"reports",
Expand Down Expand Up @@ -3884,6 +3888,7 @@ If webhook is set to have Event Grid message format then the payload will look a
"coverage",
"crashes",
"inputs",
"crashdumps",
"no_repro",
"readonly_inputs",
"reports",
Expand Down Expand Up @@ -4322,6 +4327,7 @@ If webhook is set to have Event Grid message format then the payload will look a
"coverage",
"crashes",
"inputs",
"crashdumps",
"no_repro",
"readonly_inputs",
"reports",
Expand Down Expand Up @@ -4787,6 +4793,7 @@ If webhook is set to have Event Grid message format then the payload will look a
"coverage",
"crashes",
"inputs",
"crashdumps",
"no_repro",
"readonly_inputs",
"reports",
Expand Down Expand Up @@ -5382,6 +5389,7 @@ If webhook is set to have Event Grid message format then the payload will look a
"coverage",
"crashes",
"inputs",
"crashdumps",
"no_repro",
"readonly_inputs",
"reports",
Expand Down
1 change: 1 addition & 0 deletions src/ApiService/ApiService/OneFuzzTypes/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public enum ContainerType {
Analysis,
Coverage,
Crashes,
Crashdumps,
Inputs,
NoRepro,
ReadonlyInputs,
Expand Down
27 changes: 17 additions & 10 deletions src/ApiService/ApiService/onefuzzlib/Defs.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
namespace Microsoft.OneFuzz.Service;

public static class Defs {

public static readonly IReadOnlyDictionary<TaskType, TaskDefinition> TASK_DEFINITIONS = new Dictionary<TaskType, TaskDefinition>() {
{ TaskType.Coverage ,
new TaskDefinition(
Expand Down Expand Up @@ -162,6 +161,12 @@ public static class Defs {
Value:1,
Permissions: ContainerPermission.Write
),
new ContainerDefinition(
Type:ContainerType.Crashdumps,
Compare: Compare.Equal,
Value:1,
Permissions: ContainerPermission.Write
),
new ContainerDefinition(
Type: ContainerType.Inputs,
Compare: Compare.Equal,
Expand Down Expand Up @@ -234,19 +239,23 @@ public static class Defs {
Vm: new VmDefinition(Compare: Compare.AtLeast, Value: 1),
Containers: new[] {
new ContainerDefinition(
Type:ContainerType.Setup,
Type: ContainerType.Setup,
Compare: Compare.Equal,
Value:1,
Value: 1,
Permissions: ContainerPermission.Read | ContainerPermission.List
),
new ContainerDefinition(
Type:ContainerType.Crashes,
Type: ContainerType.Crashes,
Compare: Compare.Equal,
Value:1,
Value: 1,
Permissions: ContainerPermission.Write


),
),
new ContainerDefinition(
Type: ContainerType.Crashdumps,
Compare: Compare.Equal,
Value: 1,
Permissions: ContainerPermission.Write
),
new ContainerDefinition(
Type: ContainerType.Inputs,
Compare: Compare.Equal,
Expand Down Expand Up @@ -407,8 +416,6 @@ public static class Defs {
Compare: Compare.Equal,
Value:1,
Permissions: ContainerPermission.Write


),
new ContainerDefinition(
Type: ContainerType.Inputs,
Expand Down
1 change: 1 addition & 0 deletions src/agent/onefuzz-task/src/local/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use crate::tasks::utils::parse_key_value;
pub const SETUP_DIR: &str = "setup_dir";
pub const INPUTS_DIR: &str = "inputs_dir";
pub const CRASHES_DIR: &str = "crashes_dir";
pub const CRASHDUMPS_DIR: &str = "crashdumps_dir";
pub const TARGET_WORKERS: &str = "target_workers";
pub const REPORTS_DIR: &str = "reports_dir";
pub const NO_REPRO_DIR: &str = "no_repro_dir";
Expand Down
11 changes: 9 additions & 2 deletions src/agent/onefuzz-task/src/local/libfuzzer_fuzz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
use crate::{
local::common::{
build_local_context, get_cmd_arg, get_cmd_env, get_cmd_exe, get_synced_dir, CmdType,
SyncCountDirMonitor, UiEvent, CHECK_FUZZER_HELP, CRASHES_DIR, INPUTS_DIR, TARGET_ENV,
TARGET_EXE, TARGET_OPTIONS, TARGET_WORKERS,
SyncCountDirMonitor, UiEvent, CHECK_FUZZER_HELP, CRASHDUMPS_DIR, CRASHES_DIR, INPUTS_DIR,
TARGET_ENV, TARGET_EXE, TARGET_OPTIONS, TARGET_WORKERS,
},
tasks::{
config::CommonConfig,
Expand All @@ -25,6 +25,8 @@ pub fn build_fuzz_config(
) -> Result<Config> {
let crashes = get_synced_dir(CRASHES_DIR, common.job_id, common.task_id, args)?
.monitor_count(&event_sender)?;
let crashdumps = get_synced_dir(CRASHDUMPS_DIR, common.job_id, common.task_id, args)?
.monitor_count(&event_sender)?;
let inputs = get_synced_dir(INPUTS_DIR, common.job_id, common.task_id, args)?
.monitor_count(&event_sender)?;

Expand All @@ -43,6 +45,7 @@ pub fn build_fuzz_config(
inputs,
readonly_inputs,
crashes,
crashdumps,
target_exe,
target_env,
target_options,
Expand Down Expand Up @@ -86,6 +89,10 @@ pub fn build_shared_args() -> Vec<Arg<'static, 'static>> {
.long(CRASHES_DIR)
.takes_value(true)
.required(true),
Arg::with_name(CRASHDUMPS_DIR)
.long(CRASHDUMPS_DIR)
.takes_value(true)
.required(true),
Arg::with_name(TARGET_WORKERS)
.long(TARGET_WORKERS)
.takes_value(true),
Expand Down
28 changes: 26 additions & 2 deletions src/agent/onefuzz-task/src/tasks/fuzz/libfuzzer/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use onefuzz_telemetry::{
EventData,
};
use serde::Deserialize;
use std::{collections::HashMap, path::PathBuf, sync::Arc};
use std::{collections::HashMap, io::ErrorKind, path::PathBuf, sync::Arc};
use tempfile::{tempdir_in, TempDir};
use tokio::{
io::{AsyncBufReadExt, BufReader},
Expand Down Expand Up @@ -68,6 +68,7 @@ pub struct Config<L: LibFuzzerType + Send + Sync + ?Sized> {
pub inputs: SyncedDir,
pub readonly_inputs: Option<Vec<SyncedDir>>,
pub crashes: SyncedDir,
pub crashdumps: SyncedDir,
pub target_exe: PathBuf,
pub target_env: HashMap<String, String>,
pub target_options: Vec<String>,
Expand Down Expand Up @@ -240,6 +241,8 @@ where
let mut running = fuzzer.fuzz(crash_dir.path(), local_inputs, &inputs).await?;
let notify = Arc::new(Notify::new());

let pid = running.id();

// Splitting borrow.
let stderr = running
.stderr
Expand Down Expand Up @@ -303,17 +306,38 @@ where
}
}

// check for core dumps on Linux:
// note that collecting the dumps must be enabled by the template
if let Some(pid) = pid {
// expect crash dump to exist in CWD
let filename = format!("core.{pid}");
let dest = self.config.crashdumps.local_path.join(&filename);
match tokio::fs::rename(filename, dest).await {
Err(e) if e.kind() == ErrorKind::NotFound => {
// okay, no crash dump found
}
other => other.context("moving crash dump to output directory")?,
}
}

// Windows: TODO

Ok(())
}

async fn init_directories(&self) -> Result<()> {
// input directories (init_pull):
self.config.inputs.init_pull().await?;
self.config.crashes.init().await?;
if let Some(readonly_inputs) = &self.config.readonly_inputs {
for dir in readonly_inputs {
dir.init_pull().await?;
}
}

// output directories (init):
self.config.crashes.init().await?;
self.config.crashdumps.init().await?;

Ok(())
}

Expand Down
10 changes: 5 additions & 5 deletions src/cli/onefuzz/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1001,11 +1001,10 @@ def create(
if tags is None:
tags = {}

containers_submit = []
for container_type, container in containers:
containers_submit.append(
models.TaskContainers(name=container, type=container_type)
)
containers_submit = [
models.TaskContainers(name=container, type=container_type)
for container_type, container in containers
]

config = models.TaskConfig(
containers=containers_submit,
Expand Down Expand Up @@ -1117,6 +1116,7 @@ def delete(
) -> None:
SAFE_TO_REMOVE = [
enums.ContainerType.crashes,
enums.ContainerType.crashdumps,
enums.ContainerType.setup,
enums.ContainerType.inputs,
enums.ContainerType.reports,
Expand Down
8 changes: 8 additions & 0 deletions src/cli/onefuzz/templates/libfuzzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ def _create_tasks(
fuzzer_containers = [
(ContainerType.setup, containers[ContainerType.setup]),
(ContainerType.crashes, containers[ContainerType.crashes]),
(ContainerType.crashdumps, containers[ContainerType.crashdumps]),
(ContainerType.inputs, containers[ContainerType.inputs]),
]

Expand Down Expand Up @@ -366,6 +367,7 @@ def basic(
ContainerType.setup,
ContainerType.inputs,
ContainerType.crashes,
ContainerType.crashdumps,
ContainerType.reports,
ContainerType.unique_reports,
ContainerType.unique_inputs,
Expand Down Expand Up @@ -625,6 +627,7 @@ def dotnet(
ContainerType.setup,
ContainerType.inputs,
ContainerType.crashes,
ContainerType.crashdumps,
)

if existing_inputs:
Expand All @@ -636,6 +639,7 @@ def dotnet(
fuzzer_containers = [
(ContainerType.setup, helper.containers[ContainerType.setup]),
(ContainerType.crashes, helper.containers[ContainerType.crashes]),
(ContainerType.crashdumps, helper.containers[ContainerType.crashdumps]),
(ContainerType.inputs, helper.containers[ContainerType.inputs]),
]

Expand Down Expand Up @@ -747,6 +751,7 @@ def dotnet_dll(
ContainerType.setup,
ContainerType.inputs,
ContainerType.crashes,
ContainerType.crashdumps,
ContainerType.coverage,
ContainerType.reports,
ContainerType.unique_reports,
Expand All @@ -769,6 +774,7 @@ def dotnet_dll(
fuzzer_containers = [
(ContainerType.setup, containers[ContainerType.setup]),
(ContainerType.crashes, containers[ContainerType.crashes]),
(ContainerType.crashdumps, containers[ContainerType.crashdumps]),
(ContainerType.inputs, containers[ContainerType.inputs]),
(ContainerType.tools, fuzzer_tools_container),
]
Expand Down Expand Up @@ -948,6 +954,7 @@ def qemu_user(
ContainerType.setup,
ContainerType.inputs,
ContainerType.crashes,
ContainerType.crashdumps,
ContainerType.reports,
ContainerType.unique_reports,
ContainerType.no_repro,
Expand All @@ -962,6 +969,7 @@ def qemu_user(
fuzzer_containers = [
(ContainerType.setup, helper.containers[ContainerType.setup]),
(ContainerType.crashes, helper.containers[ContainerType.crashes]),
(ContainerType.crashdumps, helper.containers[ContainerType.crashdumps]),
(ContainerType.inputs, helper.containers[ContainerType.inputs]),
]

Expand Down
Loading