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

Crash repro as task #830

Closed
wants to merge 96 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
5b98a6b
add crash repro as a task
demoray Mar 22, 2021
0d73b9f
experimental live repro using tasks
demoray Mar 22, 2021
202f0ab
Merge branch 'main' into crash-repro-as-task
demoray Apr 22, 2021
5360f03
update from recent SyncedDir changes
demoray Apr 22, 2021
b86a44d
run debugger in a loop
demoray Apr 22, 2021
35d8cb7
move heartbeat into loop
demoray Apr 23, 2021
c86ecc3
model existing APIs
demoray Apr 23, 2021
6bee24b
Merge branch 'main' into crash-repro-as-task
bmc-msft Apr 23, 2021
0a5d3dd
update webhook docs
demoray Apr 23, 2021
56f7cea
rename input to input_file and add to API
demoray Apr 23, 2021
8c1abf4
add file_name
demoray Apr 23, 2021
9021064
handle task_id expansion
demoray Apr 23, 2021
8429c4b
input file is relative to crashes container
demoray Apr 23, 2021
f6fccee
Merge branch 'main' into crash-repro-as-task
bmc-msft Apr 23, 2021
cfba620
be explicit in type assignment to help mypy
demoray Apr 23, 2021
dc36129
Merge branch 'crash-repro-as-task' of github.com:bmc-msft/onefuzz int…
demoray Apr 23, 2021
3426149
update to support getting node messages
demoray Apr 23, 2021
c9f6b16
add context to failures
demoray Apr 23, 2021
1ac3a20
late evaluation of input_path
demoray Apr 24, 2021
fa8393f
update refs for Node
demoray Apr 24, 2021
f32d962
log task_id for repro task
demoray Apr 24, 2021
2db4a26
formatting
demoray Apr 24, 2021
cb208fb
update black
demoray Apr 26, 2021
6d5c6d3
black & flush out debugger cmds
demoray Apr 26, 2021
30ec432
add logging to commands to debug
demoray Apr 26, 2021
026de37
compare against an Instant since the sleep isn't being polled
demoray Apr 26, 2021
5b59cb3
wait for proxy IP
demoray Apr 26, 2021
acedb7b
update scalesetproxy log level
demoray Apr 26, 2021
dac9212
only one yield
demoray Apr 26, 2021
259c974
remove debug prints
demoray Apr 26, 2021
7b03e64
Merge branch 'main' into crash-repro-as-task
bmc-msft Apr 26, 2021
3621e5a
Merge branch 'main' into crash-repro-as-task
bmc-msft Apr 26, 2021
72afa4e
Merge branch 'main' into crash-repro-as-task
demoray Apr 26, 2021
40c4b19
remove extra info
demoray Apr 26, 2021
cad9c67
Merge branch 'main' into crash-repro-as-task
bmc-msft Apr 26, 2021
3dd39a5
Merge branch 'main' into crash-repro-as-task
demoray Apr 26, 2021
750fcbb
continued updates
demoray Apr 26, 2021
db09ffc
Merge branch 'main' into crash-repro-as-task
bmc-msft Apr 26, 2021
3610c16
monitor for failed tasks during initial connection.
demoray Apr 27, 2021
f3b7013
provide more details in add_ssh_key failures
demoray Apr 27, 2021
2faf328
fix missing comma
demoray Apr 27, 2021
88e12a3
Merge branch 'main' into crash-repro-as-task
bmc-msft May 4, 2021
19a64be
Merge branch 'main' into crash-repro-as-task
bmc-msft May 11, 2021
28bdb2a
Merge branch 'main' into crash-repro-as-task
bmc-msft May 17, 2021
68bba3a
Merge branch 'main' into crash-repro-as-task
bmc-msft May 17, 2021
61b6f85
Merge branch 'main' into crash-repro-as-task
bmc-msft May 19, 2021
0cea4c6
Merge branch 'main' into crash-repro-as-task
bmc-msft May 25, 2021
cc99ca4
use self.success for repro tasks
demoray May 25, 2021
9a230d0
set ssh keys only once
demoray May 25, 2021
57e9cb0
add specific logging for set_halt
demoray May 26, 2021
333ebf3
address issue deleting nodes that fail heartbeats
demoray May 26, 2021
5cbee79
clarify log message
demoray May 26, 2021
b8dec49
address feedback
demoray May 26, 2021
9df75b7
save more details to the failure context
demoray May 26, 2021
f4f16b1
Merge branch 'main' into crash-repro-as-task
bmc-msft May 26, 2021
cfbf3a7
handle proxies not deleting
demoray May 26, 2021
96d1d07
Merge branch 'main' into crash-repro-as-task
bmc-msft May 26, 2021
e3a1b45
Merge branch 'main' into crash-repro-as-task
bmc-msft May 26, 2021
952854d
Merge branch 'main' into crash-repro-as-task
bmc-msft May 26, 2021
92978a5
Merge branch 'crash-repro-as-task' of github.com:bmc-msft/onefuzz int…
demoray May 26, 2021
8f9ca4d
explain which repro is being tested
demoray May 26, 2021
e41c286
check task in the wait loop callbacks
demoray May 26, 2021
59a5867
Merge branch 'main' into crash-repro-as-task
bmc-msft May 26, 2021
0e05b51
add stop_after_use feature similar to delete_after_use for old repro
demoray May 27, 2021
02fa8b6
reduce cdb interaction until we connect in
demoray May 27, 2021
8453d61
Merge branch 'main' into crash-repro-as-task
bmc-msft May 27, 2021
dc28d3c
rename agent task to analysis_single
demoray May 27, 2021
b66d66f
Merge branch 'crash-repro-as-task' of github.com:bmc-msft/onefuzz int…
demoray May 27, 2021
bfba12e
fix command info
demoray May 27, 2021
fc54ab4
add an optional initial delay for heartbeats
demoray May 27, 2021
55baef0
Merge branch 'add-heartbeat-initialization-delay' into crash-repro-as…
demoray May 27, 2021
5cf835a
set initialization delay
demoray May 27, 2021
d03f034
wait for heartbeats before starting the task
demoray May 27, 2021
5a82733
log the signalr event
demoray May 28, 2021
17e613d
Merge branch 'main' into crash-repro-as-task
demoray Jun 9, 2021
de83031
fix merge issue
demoray Jun 9, 2021
16312af
Merge branch 'main' into crash-repro-as-task
bmc-msft Jun 14, 2021
a09e4c9
Merge branch 'main' into crash-repro-as-task
bmc-msft Jun 29, 2021
17f60c9
Merge branch 'main' into crash-repro-as-task
bmc-msft Jul 1, 2021
8bb2400
fix incorrect wait cmd
demoray Jul 1, 2021
9a5393b
launch repros iteratively
demoray Jul 1, 2021
91a8539
only remove SYSTEM if it's there
demoray Jul 1, 2021
ba0aacb
fix to_string
demoray Jul 1, 2021
e5f3d5e
remove debugging
demoray Jul 1, 2021
d649455
Merge branch 'main' into crash-repro-as-task
bmc-msft Jul 1, 2021
3c32292
Apply suggestions from code review
bmc-msft Jul 2, 2021
880050a
Merge branch 'main' into crash-repro-as-task
bmc-msft Jul 2, 2021
67b32ab
Merge branch 'main' into crash-repro-as-task
demoray Jul 6, 2021
cee87dc
remove stray }
demoray Jul 6, 2021
474c19a
Merge branch 'main' into crash-repro-as-task
bmc-msft Jul 6, 2021
31de28e
Merge branch 'main' into crash-repro-as-task
bmc-msft Aug 23, 2021
d410653
Merge branch 'main' into crash-repro-as-task
bmc-msft Aug 23, 2021
add906f
Merge branch 'main' into crash-repro-as-task
bmc-msft Sep 20, 2021
5d8b57a
Merge branch 'main' into crash-repro-as-task
bmc-msft Sep 23, 2021
8f40e99
Merge branch 'main' into crash-repro-as-task
bmc-msft Sep 24, 2021
1979d88
Merge branch 'main' into crash-repro-as-task
bmc-msft Oct 13, 2021
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
59 changes: 50 additions & 9 deletions docs/webhook_events.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,10 @@ Each event will be submitted via HTTP POST to the user provided URL.
"title": "Generator Options",
"type": "array"
},
"input_file": {
"title": "Input File",
"type": "string"
},
"minimized_stack_depth": {
"title": "Minimized Stack Depth",
"type": "integer"
Expand Down Expand Up @@ -528,7 +532,8 @@ Each event will be submitted via HTTP POST to the user provided URL.
"generic_merge",
"generic_generator",
"generic_crash_report",
"generic_regression"
"generic_regression",
"analysis_single"
],
"title": "TaskType"
},
Expand Down Expand Up @@ -1073,7 +1078,8 @@ Each event will be submitted via HTTP POST to the user provided URL.
"generic_merge",
"generic_generator",
"generic_crash_report",
"generic_regression"
"generic_regression",
"analysis_single"
],
"title": "TaskType"
},
Expand Down Expand Up @@ -2143,6 +2149,10 @@ Each event will be submitted via HTTP POST to the user provided URL.
"title": "Generator Options",
"type": "array"
},
"input_file": {
"title": "Input File",
"type": "string"
},
"minimized_stack_depth": {
"title": "Minimized Stack Depth",
"type": "integer"
Expand Down Expand Up @@ -2272,7 +2282,8 @@ Each event will be submitted via HTTP POST to the user provided URL.
"generic_merge",
"generic_generator",
"generic_crash_report",
"generic_regression"
"generic_regression",
"analysis_single"
],
"title": "TaskType"
},
Expand Down Expand Up @@ -2855,6 +2866,10 @@ Each event will be submitted via HTTP POST to the user provided URL.
"title": "Generator Options",
"type": "array"
},
"input_file": {
"title": "Input File",
"type": "string"
},
"minimized_stack_depth": {
"title": "Minimized Stack Depth",
"type": "integer"
Expand Down Expand Up @@ -2984,7 +2999,8 @@ Each event will be submitted via HTTP POST to the user provided URL.
"generic_merge",
"generic_generator",
"generic_crash_report",
"generic_regression"
"generic_regression",
"analysis_single"
],
"title": "TaskType"
},
Expand Down Expand Up @@ -3358,6 +3374,10 @@ Each event will be submitted via HTTP POST to the user provided URL.
"title": "Generator Options",
"type": "array"
},
"input_file": {
"title": "Input File",
"type": "string"
},
"minimized_stack_depth": {
"title": "Minimized Stack Depth",
"type": "integer"
Expand Down Expand Up @@ -3487,7 +3507,8 @@ Each event will be submitted via HTTP POST to the user provided URL.
"generic_merge",
"generic_generator",
"generic_crash_report",
"generic_regression"
"generic_regression",
"analysis_single"
],
"title": "TaskType"
},
Expand Down Expand Up @@ -3806,6 +3827,10 @@ Each event will be submitted via HTTP POST to the user provided URL.
"title": "Generator Options",
"type": "array"
},
"input_file": {
"title": "Input File",
"type": "string"
},
"minimized_stack_depth": {
"title": "Minimized Stack Depth",
"type": "integer"
Expand Down Expand Up @@ -3935,7 +3960,8 @@ Each event will be submitted via HTTP POST to the user provided URL.
"generic_merge",
"generic_generator",
"generic_crash_report",
"generic_regression"
"generic_regression",
"analysis_single"
],
"title": "TaskType"
},
Expand Down Expand Up @@ -4228,6 +4254,10 @@ Each event will be submitted via HTTP POST to the user provided URL.
"title": "Generator Options",
"type": "array"
},
"input_file": {
"title": "Input File",
"type": "string"
},
"minimized_stack_depth": {
"title": "Minimized Stack Depth",
"type": "integer"
Expand Down Expand Up @@ -4371,7 +4401,8 @@ Each event will be submitted via HTTP POST to the user provided URL.
"generic_merge",
"generic_generator",
"generic_crash_report",
"generic_regression"
"generic_regression",
"analysis_single"
],
"title": "TaskType"
},
Expand Down Expand Up @@ -4677,6 +4708,10 @@ Each event will be submitted via HTTP POST to the user provided URL.
"title": "Generator Options",
"type": "array"
},
"input_file": {
"title": "Input File",
"type": "string"
},
"minimized_stack_depth": {
"title": "Minimized Stack Depth",
"type": "integer"
Expand Down Expand Up @@ -4806,7 +4841,8 @@ Each event will be submitted via HTTP POST to the user provided URL.
"generic_merge",
"generic_generator",
"generic_crash_report",
"generic_regression"
"generic_regression",
"analysis_single"
],
"title": "TaskType"
},
Expand Down Expand Up @@ -6299,6 +6335,10 @@ Each event will be submitted via HTTP POST to the user provided URL.
"title": "Generator Options",
"type": "array"
},
"input_file": {
"title": "Input File",
"type": "string"
},
"minimized_stack_depth": {
"title": "Minimized Stack Depth",
"type": "integer"
Expand Down Expand Up @@ -6442,7 +6482,8 @@ Each event will be submitted via HTTP POST to the user provided URL.
"generic_merge",
"generic_generator",
"generic_crash_report",
"generic_regression"
"generic_regression",
"analysis_single"
],
"title": "TaskType"
},
Expand Down
1 change: 1 addition & 0 deletions src/agent/onefuzz-agent/src/tasks/analysis/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
// Licensed under the MIT License.

pub mod generic;
pub mod single;
124 changes: 124 additions & 0 deletions src/agent/onefuzz-agent/src/tasks/analysis/single.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use crate::tasks::{config::CommonConfig, heartbeat::HeartbeatSender};
use anyhow::{Context, Result};
use onefuzz::{expand::Expand, fs::set_executable, process::monitor_process, syncdir::SyncedDir};
use serde::Deserialize;
use std::time::Duration;
use std::{collections::HashMap, path::PathBuf, process::Stdio};
use tokio::process::Command;

const INITIAL_DELAY: Duration = Duration::from_millis(1);

#[derive(Debug, Deserialize)]
pub struct Config {
pub analyzer_exe: String,
pub analyzer_options: Vec<String>,
pub analyzer_env: HashMap<String, String>,

pub target_exe: PathBuf,
pub target_options: Vec<String>,
pub crashes: SyncedDir,
pub input_file: String,

pub tools: Option<SyncedDir>,

#[serde(flatten)]
pub common: CommonConfig,
}

pub async fn run(config: Config) -> Result<()> {
config
.crashes
.init_pull()
.await
.context("unable to sync crashes")?;
if let Some(tools) = &config.tools {
tools.init_pull().await.context("unable to sync tools")?;
set_executable(&tools.local_path)
.await
.context("unable to set tools as executable")?;
}

run_tool(&config).await
}

pub async fn run_tool(config: &Config) -> Result<()> {
let heartbeat = config.common.init_heartbeat(Some(INITIAL_DELAY)).await?;
let expand = Expand::new()
.target_exe(&config.target_exe)
.target_options(&config.target_options)
.analyzer_exe(&config.analyzer_exe)
.analyzer_options(&config.analyzer_options)
.crashes(&config.crashes.local_path)
.set_optional_ref(&config.tools, |tester, key| {
tester.tools_dir(&key.local_path)
})
.setup_dir(&config.common.setup_dir)
.job_id(&config.common.job_id)
.task_id(&config.common.task_id)
.set_optional_ref(&config.common.microsoft_telemetry_key, |tester, key| {
tester.microsoft_telemetry_key(&key)
})
.set_optional_ref(&config.common.instance_telemetry_key, |tester, key| {
tester.instance_telemetry_key(&key)
})
.set_optional_ref(
&config.crashes.remote_path.clone().and_then(|u| u.account()),
|tester, account| tester.crashes_account(account),
)
.set_optional_ref(
&config
.crashes
.remote_path
.clone()
.and_then(|u| u.container()),
|tester, container| tester.crashes_container(container),
);

let input_path = expand
.evaluate_value(format!("{{crashes}}/{}", config.input_file))
.context("unable to expand input_path")?;
let expand = expand.input_path(input_path);

let analyzer_path = expand
.evaluate_value(&config.analyzer_exe)
.context("expanding analyzer_exe failed")?;

loop {
let mut cmd = Command::new(&analyzer_path);
cmd.kill_on_drop(true)
.env_remove("RUST_LOG")
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::piped());

for arg in expand.evaluate(&config.analyzer_options)? {
cmd.arg(arg);
}

for (k, v) in &config.analyzer_env {
cmd.env(
k,
expand
.evaluate_value(v)
.context("expanding analyzer_env failed")?,
);
}

info!("analyzing input with {:?}", cmd);
let output = cmd
.spawn()
.with_context(|| format!("analyzer failed to start: {}", analyzer_path))?;

heartbeat.alive();

// while we monitor the runtime of the debugger, we don't fail the task if
// the debugger exits non-zero. This frequently happens during normal use of
// debuggers.
monitor_process(output, "crash-repro".to_string(), true, None)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we be storing the logs of the analysis ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. monitor_process logs stdout and stderr to application insights.

.await
.ok();
}
}
10 changes: 10 additions & 0 deletions src/agent/onefuzz-agent/src/tasks/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ pub enum Config {

#[serde(alias = "generic_regression")]
GenericRegression(regression::generic::Config),

#[serde(alias = "analysis_single")]
AnalysisSingle(analysis::single::Config),
}

impl Config {
Expand Down Expand Up @@ -130,6 +133,7 @@ impl Config {
Config::GenericSupervisor(c) => &mut c.common,
Config::GenericGenerator(c) => &mut c.common,
Config::GenericRegression(c) => &mut c.common,
Config::AnalysisSingle(c) => &mut c.common,
}
}

Expand All @@ -149,6 +153,7 @@ impl Config {
Config::GenericSupervisor(c) => &c.common,
Config::GenericGenerator(c) => &c.common,
Config::GenericRegression(c) => &c.common,
Config::AnalysisSingle(c) => &c.common,
}
}

Expand All @@ -168,6 +173,7 @@ impl Config {
Config::GenericSupervisor(_) => "generic_supervisor",
Config::GenericGenerator(_) => "generic_generator",
Config::GenericRegression(_) => "generic_regression",
Config::AnalysisSingle(_) => "analysis_single",
};

match self {
Expand All @@ -177,6 +183,9 @@ impl Config {
Config::GenericAnalysis(c) => {
event!(task_start; EventData::Type = event_type, EventData::ToolName = c.analyzer_exe.clone());
}
Config::AnalysisSingle(c) => {
event!(task_start; EventData::Type = event_type, EventData::ToolName = c.analyzer_exe.clone());
}
_ => {
event!(task_start; EventData::Type = event_type);
}
Expand Down Expand Up @@ -238,6 +247,7 @@ impl Config {
.run()
.await
}
Config::AnalysisSingle(config) => analysis::single::run(config).await,
}
}
}
3 changes: 3 additions & 0 deletions src/api-service/__app__/onefuzzlib/tasks/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,9 @@ def build_task_config(
else True
)

if TaskFeature.input_file in definition.features:
config.input_file = task_config.task.input_file

if TaskFeature.coverage_filter in definition.features:
coverage_filter = task_config.task.coverage_filter

Expand Down
Loading