Add 'setup_dir' to LD_LIBRARY_PATH for unix based libfuzzer targets (#682)

This commit is contained in:
bmc-msft
2021-03-17 12:40:05 -04:00
committed by GitHub
parent cd6621bb89
commit 4ad52c80aa
3 changed files with 82 additions and 14 deletions

View File

@ -6,16 +6,19 @@ use std::ffi::OsString;
use std::path::PathBuf;
pub const PATH: &str = "PATH";
pub const LD_LIBRARY_PATH: &str = "LD_LIBRARY_PATH";
pub fn get_path_with_directory(to_add: &PathBuf) -> Result<OsString> {
match std::env::var_os(PATH) {
Some(path) => {
let mut paths: Vec<_> = std::env::split_paths(&path).collect();
if !paths.contains(to_add) {
paths.push(to_add.clone())
}
Ok(std::env::join_paths(paths)?)
}
pub fn update_path(path: OsString, to_add: &PathBuf) -> Result<OsString> {
let mut paths: Vec<_> = std::env::split_paths(&path).collect();
if !paths.contains(to_add) {
paths.push(to_add.clone())
}
Ok(std::env::join_paths(paths)?)
}
pub fn get_path_with_directory(variable: &str, to_add: &PathBuf) -> Result<OsString> {
match std::env::var_os(variable) {
Some(path) => update_path(path, to_add),
None => Ok(to_add.clone().into()),
}
}

View File

@ -5,6 +5,7 @@
use crate::{
asan::{add_asan_log_env, check_asan_path, check_asan_string, AsanLog},
env::{get_path_with_directory, update_path, LD_LIBRARY_PATH, PATH},
expand::Expand,
process::run_cmd,
};
@ -25,6 +26,8 @@ pub struct Tester<'a> {
check_asan_stderr: bool,
check_debugger: bool,
check_retry_count: u64,
add_setup_to_ld_library_path: bool,
add_setup_to_path: bool,
}
#[derive(Debug)]
@ -58,6 +61,8 @@ impl<'a> Tester<'a> {
check_asan_stderr: false,
check_debugger: false,
check_retry_count: 0,
add_setup_to_ld_library_path: false,
add_setup_to_path: false,
}
}
@ -96,6 +101,20 @@ impl<'a> Tester<'a> {
}
}
pub fn add_setup_to_ld_library_path(self, value: bool) -> Self {
Self {
add_setup_to_ld_library_path: value,
..self
}
}
pub fn add_setup_to_path(self, value: bool) -> Self {
Self {
add_setup_to_path: value,
..self
}
}
pub fn set_optional<T>(self, value: Option<T>, setter: impl FnOnce(Self, T) -> Self) -> Self {
if let Some(value) = value {
setter(self, value)
@ -241,6 +260,25 @@ impl<'a> Tester<'a> {
env.insert(k.clone(), expand.evaluate_value(v)?);
}
let setup_dir = &self.setup_dir.to_path_buf();
if self.add_setup_to_path {
let new_path = match env.get(PATH) {
Some(v) => update_path(v.clone().into(), &setup_dir)?,
None => get_path_with_directory(PATH, &setup_dir)?,
};
env.insert(PATH.to_string(), new_path.to_string_lossy().to_string());
}
if self.add_setup_to_ld_library_path {
let new_path = match env.get(LD_LIBRARY_PATH) {
Some(v) => update_path(v.clone().into(), &setup_dir)?,
None => get_path_with_directory(LD_LIBRARY_PATH, &setup_dir)?,
};
env.insert(
LD_LIBRARY_PATH.to_string(),
new_path.to_string_lossy().to_string(),
);
}
if let Some(asan_dir) = &asan_dir {
add_asan_log_env(&mut env, asan_dir.path());
}

View File

@ -2,7 +2,7 @@
// Licensed under the MIT License.
use crate::{
env::{get_path_with_directory, PATH},
env::{get_path_with_directory, LD_LIBRARY_PATH, PATH},
expand::Expand,
input_tester::{TestResult, Tester},
};
@ -51,13 +51,20 @@ impl<'a> LibFuzzer<'a> {
let mut cmd = Command::new(&self.exe);
cmd.kill_on_drop(true)
.env(PATH, get_path_with_directory(&self.setup_dir)?)
.env(PATH, get_path_with_directory(PATH, &self.setup_dir)?)
.env_remove("RUST_LOG")
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.arg("-help=1");
if cfg!(target_family = "unix") {
cmd.env(
LD_LIBRARY_PATH,
get_path_with_directory(LD_LIBRARY_PATH, &self.setup_dir)?,
);
}
let expand = Expand::new()
.target_exe(&self.exe)
.target_options(&self.options)
@ -102,7 +109,7 @@ impl<'a> LibFuzzer<'a> {
let mut cmd = Command::new(&self.exe);
cmd.kill_on_drop(true)
.env(PATH, get_path_with_directory(&self.setup_dir)?)
.env(PATH, get_path_with_directory(PATH, &self.setup_dir)?)
.env_remove("RUST_LOG")
.stdout(Stdio::null())
.stderr(Stdio::piped());
@ -117,6 +124,13 @@ impl<'a> LibFuzzer<'a> {
cmd.arg(o);
}
if cfg!(target_family = "unix") {
cmd.env(
LD_LIBRARY_PATH,
get_path_with_directory(LD_LIBRARY_PATH, &self.setup_dir)?,
);
}
// check if a max_time is already set
if self
.options
@ -163,10 +177,16 @@ impl<'a> LibFuzzer<'a> {
let mut options = self.options.to_owned();
options.push("{input}".to_string());
let tester = Tester::new(&self.setup_dir, &self.exe, &options, &self.env)
let mut tester = Tester::new(&self.setup_dir, &self.exe, &options, &self.env)
.check_asan_stderr(true)
.check_retry_count(retry)
.add_setup_to_path(true)
.set_optional(timeout, |tester, timeout| tester.timeout(timeout));
if cfg!(target_family = "unix") {
tester = tester.add_setup_to_ld_library_path(true);
}
tester.test_input(test_input.as_ref()).await
}
@ -184,13 +204,20 @@ impl<'a> LibFuzzer<'a> {
let mut cmd = Command::new(&self.exe);
cmd.kill_on_drop(true)
.env(PATH, get_path_with_directory(&self.setup_dir)?)
.env(PATH, get_path_with_directory(PATH, &self.setup_dir)?)
.env_remove("RUST_LOG")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.arg("-merge=1")
.arg(corpus_dir.as_ref());
if cfg!(target_family = "unix") {
cmd.env(
LD_LIBRARY_PATH,
get_path_with_directory(LD_LIBRARY_PATH, &self.setup_dir)?,
);
}
for dir in corpus_dirs {
cmd.arg(dir.as_ref());
}