mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-17 04:18:07 +00:00
Check for missing shared libs on failed LibFuzzer -help
check (#1812)
This commit is contained in:
1
src/agent/Cargo.lock
generated
1
src/agent/Cargo.lock
generated
@ -1974,6 +1974,7 @@ dependencies = [
|
||||
"cpp_demangle",
|
||||
"debugger",
|
||||
"dunce",
|
||||
"dynamic-library",
|
||||
"futures",
|
||||
"futures-util",
|
||||
"hex",
|
||||
|
@ -12,6 +12,7 @@ async-trait = "0.1"
|
||||
base64 = "0.13"
|
||||
bytes = "1.1"
|
||||
dunce = "1.0"
|
||||
dynamic-library = { path = "../dynamic-library" }
|
||||
futures = "0.3"
|
||||
futures-util = "0.3"
|
||||
hex = "0.4"
|
||||
|
@ -56,15 +56,35 @@ impl<'a> LibFuzzer<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
// Build an async `Command`.
|
||||
async fn build_command(
|
||||
&self,
|
||||
fault_dir: Option<&Path>,
|
||||
corpus_dir: Option<&Path>,
|
||||
extra_corpus_dirs: Option<&[&Path]>,
|
||||
) -> Result<Command> {
|
||||
let mut cmd = Command::new(&self.exe);
|
||||
cmd.kill_on_drop(true)
|
||||
.env(PATH, get_path_with_directory(PATH, &self.setup_dir)?)
|
||||
let std_cmd = self
|
||||
.build_std_command(fault_dir, corpus_dir, extra_corpus_dirs)
|
||||
.await?;
|
||||
|
||||
// Make async.
|
||||
let mut cmd = Command::from(std_cmd);
|
||||
|
||||
// Terminate the process if the `Child` handle is dropped.
|
||||
cmd.kill_on_drop(true);
|
||||
|
||||
Ok(cmd)
|
||||
}
|
||||
|
||||
// Build a non-async `Command`.
|
||||
async fn build_std_command(
|
||||
&self,
|
||||
fault_dir: Option<&Path>,
|
||||
corpus_dir: Option<&Path>,
|
||||
extra_corpus_dirs: Option<&[&Path]>,
|
||||
) -> Result<std::process::Command> {
|
||||
let mut cmd = std::process::Command::new(&self.exe);
|
||||
cmd.env(PATH, get_path_with_directory(PATH, &self.setup_dir)?)
|
||||
.env_remove("RUST_LOG")
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::piped())
|
||||
@ -199,6 +219,9 @@ impl<'a> LibFuzzer<'a> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Invoke `{target_exe} -help=1`. If this succeeds, then the dynamic linker is at
|
||||
/// least able to satisfy the fuzzer's shared library dependencies. User-authored
|
||||
/// dynamic loading may still fail later on, e.g. in `LLVMFuzzerInitialize()`.
|
||||
async fn check_help(&self) -> Result<()> {
|
||||
let mut cmd = self.build_command(None, None, None).await?;
|
||||
cmd.arg("-help=1");
|
||||
@ -209,12 +232,49 @@ impl<'a> LibFuzzer<'a> {
|
||||
.wait_with_output()
|
||||
.await
|
||||
.with_context(|| format_err!("libfuzzer failed to run: {}", self.exe.display()))?;
|
||||
|
||||
if !result.status.success() {
|
||||
bail!("fuzzer does not respond to '-help=1'. output:{:?}", result);
|
||||
// To provide user-actionable errors, try to identify any missing shared libraries.
|
||||
match self.find_missing_libraries().await {
|
||||
Ok(missing) => {
|
||||
if missing.is_empty() {
|
||||
bail!("fuzzer does not respond to '-help=1'. no missing shared libraries detected. output: {:?}", result);
|
||||
} else {
|
||||
let missing = missing.join(", ");
|
||||
|
||||
bail!("fuzzer does not respond to '-help=1'. missing shared libraries: {}. output: {:?}", missing, result);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
bail!("fuzzer does not respond to '-help=1'. additional error while checking for missing shared libraries: {}. output: {:?}", err, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
async fn find_missing_libraries(&self) -> Result<Vec<String>> {
|
||||
let cmd = self.build_std_command(None, None, None).await?;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
let blocking = move || dynamic_library::linux::find_missing(cmd);
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let blocking = move || dynamic_library::windows::find_missing(cmd);
|
||||
|
||||
let missing = tokio::task::spawn_blocking(blocking).await??;
|
||||
let missing = missing.into_iter().map(|m| m.name).collect();
|
||||
|
||||
Ok(missing)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
async fn find_missing_libraries(&self) -> Result<Vec<String>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub async fn fuzz(
|
||||
&self,
|
||||
fault_dir: impl AsRef<Path>,
|
||||
|
Reference in New Issue
Block a user