Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .github/workflows/aarch64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
export CARGO_TERM_COLOR=always
export CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
apt-get update && apt-get install -y gdb pip curl python3.12-dev clang llvm build-essential binutils lld lua5.4
update-alternatives --set cc /usr/bin/clang
curl https://sh.rustup.rs -o rustup.sh && chmod +x rustup.sh && \
./rustup.sh -y && rm rustup.sh
run: |
Expand Down
14 changes: 14 additions & 0 deletions casr/src/bin/casr-csharp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@
.value_name("PREFIX")
.help("Path prefix to strip from stacktrace and crash line"),
)
.arg(
Arg::new("ld-preload")
.long("ld-preload")
.env("CASR_PRELOAD")
.action(ArgAction::Set)
.num_args(1..)
.value_name("LIBS")
.value_parser(clap::value_parser!(String))
.help("Set LD_PRELOAD for the target program without disrupting the CASR process itself (both ` ` and `:` are valid delimiter)")
)
.arg(
Arg::new("ARGS")
.action(ArgAction::Set)
Expand Down Expand Up @@ -107,6 +117,10 @@

// Run program.
let mut csharp_cmd = Command::new(argv[0]);
// Set ld preload
if let Some(ld_preload) = util::get_ld_preload(&matches) {
csharp_cmd.env("LD_PRELOAD", ld_preload);

Check warning on line 122 in casr/src/bin/casr-csharp.rs

View check run for this annotation

Codecov / codecov/patch

casr/src/bin/casr-csharp.rs#L122

Added line #L122 was not covered by tests
}
if let Some(ref file) = stdin_file {
csharp_cmd.stdin(std::fs::File::open(file)?);
}
Expand Down
14 changes: 14 additions & 0 deletions casr/src/bin/casr-java.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ fn main() -> Result<()> {
.value_name("PREFIX")
.help("Path prefix to strip from stacktrace and crash line"),
)
.arg(
Arg::new("ld-preload")
.long("ld-preload")
.env("CASR_PRELOAD")
.action(ArgAction::Set)
.num_args(1..)
.value_name("LIBS")
.value_parser(clap::value_parser!(String))
.help("Set LD_PRELOAD for the target program without disrupting the CASR process itself (both ` ` and `:` are valid delimiter)")
)
.arg(
Arg::new("ARGS")
.action(ArgAction::Set)
Expand Down Expand Up @@ -111,6 +121,10 @@ fn main() -> Result<()> {

// Run program.
let mut java_cmd = Command::new(argv[0]);
// Set ld preload
if let Some(ld_preload) = util::get_ld_preload(&matches) {
java_cmd.env("LD_PRELOAD", ld_preload);
}
if let Some(ref file) = stdin_file {
java_cmd.stdin(std::fs::File::open(file)?);
}
Expand Down
14 changes: 14 additions & 0 deletions casr/src/bin/casr-js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ fn main() -> Result<()> {
.value_name("PREFIX")
.help("Path prefix to strip from stacktrace and crash line"),
)
.arg(
Arg::new("ld-preload")
.long("ld-preload")
.env("CASR_PRELOAD")
.action(ArgAction::Set)
.num_args(1..)
.value_name("LIBS")
.value_parser(clap::value_parser!(String))
.help("Set LD_PRELOAD for the target program without disrupting the CASR process itself (both ` ` and `:` are valid delimiter)")
)
.arg(
Arg::new("ARGS")
.action(ArgAction::Set)
Expand Down Expand Up @@ -99,6 +109,10 @@ fn main() -> Result<()> {

// Run program.
let mut js_cmd = Command::new(argv[0]);
// Set ld preload
if let Some(ld_preload) = util::get_ld_preload(&matches) {
js_cmd.env("LD_PRELOAD", ld_preload);
}
if let Some(ref file) = stdin_file {
js_cmd.stdin(std::fs::File::open(file)?);
}
Expand Down
8 changes: 6 additions & 2 deletions casr/src/bin/casr-libfuzzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
};

use std::collections::HashMap;
use std::env;
use std::fs;
use std::path::{Path, PathBuf};

fn main() -> Result<()> {
let matches = clap::Command::new("casr-libfuzzer")
.version(clap::crate_version!())
.about("Triage crashes found by libFuzzer based fuzzer (C/C++/go-fuzz/Atheris/Jazzer/Jazzer.js/jsfuzz) or LibAFL based fuzzer")
.about("Triage crashes found by libFuzzer based fuzzer (C/C++/go-fuzz/Atheris/Jazzer/Jazzer.js/jsfuzz/luzer) or LibAFL based fuzzer")
.term_width(90)
.arg(
Arg::new("log-level")
Expand Down Expand Up @@ -147,7 +148,10 @@
// Get tool.
let mut envs = HashMap::new();
let tool = if hint == "python" || hint == "auto" && argv[0].ends_with(".py") {
envs.insert("LD_PRELOAD".to_string(), util::get_atheris_lib()?);
// NOTE: https://doc.rust-lang.org/std/env/fn.var.html#errors
if env::var("CASR_PRELOAD").is_err() {
envs.insert("CASR_PRELOAD".to_string(), util::get_atheris_lib()?);
}

Check warning on line 154 in casr/src/bin/casr-libfuzzer.rs

View check run for this annotation

Codecov / codecov/patch

casr/src/bin/casr-libfuzzer.rs#L154

Added line #L154 was not covered by tests
"casr-python"
} else if hint == "java"
|| hint == "auto" && (argv[0].ends_with("jazzer") || argv[0].ends_with("java"))
Expand Down
14 changes: 14 additions & 0 deletions casr/src/bin/casr-lua.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@
.value_name("PREFIX")
.help("Path prefix to strip from stacktrace"),
)
.arg(
Arg::new("ld-preload")
.long("ld-preload")
.env("CASR_PRELOAD")
.action(ArgAction::Set)
.num_args(1..)
.value_name("LIBS")
.value_parser(clap::value_parser!(String))
.help("Set LD_PRELOAD for the target program without disrupting the CASR process itself (both ` ` and `:` are valid delimiter)")
)
.arg(
Arg::new("ARGS")
.action(ArgAction::Set)
Expand Down Expand Up @@ -104,6 +114,10 @@

// Run program.
let mut cmd = Command::new(argv[0]);
// Set ld preload
if let Some(ld_preload) = util::get_ld_preload(&matches) {
cmd.env("LD_PRELOAD", ld_preload);

Check warning on line 119 in casr/src/bin/casr-lua.rs

View check run for this annotation

Codecov / codecov/patch

casr/src/bin/casr-lua.rs#L119

Added line #L119 was not covered by tests
}
if let Some(ref file) = stdin_file {
cmd.stdin(std::fs::File::open(file)?);
}
Expand Down
14 changes: 14 additions & 0 deletions casr/src/bin/casr-python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ fn main() -> Result<()> {
.value_name("PREFIX")
.help("Path prefix to strip from stacktrace"),
)
.arg(
Arg::new("ld-preload")
.long("ld-preload")
.env("CASR_PRELOAD")
.action(ArgAction::Set)
.num_args(1..)
.value_name("LIBS")
.value_parser(clap::value_parser!(String))
.help("Set LD_PRELOAD for the target program without disrupting the CASR process itself (both ` ` and `:` are valid delimiter)")
)
.arg(
Arg::new("ARGS")
.action(ArgAction::Set)
Expand Down Expand Up @@ -103,6 +113,10 @@ fn main() -> Result<()> {

// Run program.
let mut python_cmd = Command::new(argv[0]);
// Set ld preload
if let Some(ld_preload) = util::get_ld_preload(&matches) {
python_cmd.env("LD_PRELOAD", ld_preload);
}
if let Some(ref file) = stdin_file {
python_cmd.stdin(std::fs::File::open(file)?);
}
Expand Down
14 changes: 14 additions & 0 deletions casr/src/bin/casr-san.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ fn main() -> Result<()> {
.value_name("PREFIX")
.help("Path prefix to strip from stacktrace and crash line"),
)
.arg(
Arg::new("ld-preload")
.long("ld-preload")
.env("CASR_PRELOAD")
.action(ArgAction::Set)
.num_args(1..)
.value_name("LIBS")
.value_parser(clap::value_parser!(String))
.help("Set LD_PRELOAD for the target program without disrupting the CASR process itself (both ` ` and `:` are valid delimiter)")
)
.arg(
Arg::new("ARGS")
.action(ArgAction::Set)
Expand Down Expand Up @@ -139,6 +149,10 @@ fn main() -> Result<()> {

// Run program with sanitizers.
let mut sanitizers_cmd = Command::new(argv[0]);
// Set ld preload
if let Some(ld_preload) = util::get_ld_preload(&matches) {
sanitizers_cmd.env("LD_PRELOAD", ld_preload);
}
if let Some(ref file) = stdin_file {
sanitizers_cmd.stdin(std::fs::File::open(file).unwrap());
}
Expand Down
25 changes: 23 additions & 2 deletions casr/src/bin/casr-ubsan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,16 @@
///
/// * `timeout` - target program timeout
///
/// * `ld_preload` - LD_PRELOAD value
///
/// # Returns value
///
/// Vector of extracted ubsan warnings with crash lines
fn extract_warnings(
input: &PathBuf,
argv: &[&str],
timeout: u64,
ld_preload: &Option<String>,
) -> Result<Vec<(UbsanWarning, CrashLine)>> {
// Get command line argv
let mut argv = argv.to_owned();
Expand All @@ -54,6 +57,10 @@
};
// Run program.
let mut cmd = Command::new(argv[0]);
// Set ld preload
if let Some(ld_preload) = ld_preload {
cmd.env("LD_PRELOAD", ld_preload);

Check warning on line 62 in casr/src/bin/casr-ubsan.rs

View check run for this annotation

Codecov / codecov/patch

casr/src/bin/casr-ubsan.rs#L62

Added line #L62 was not covered by tests
}
cmd.stdout(Stdio::null()).stderr(Stdio::piped());
if stdin {
let Ok(file) = fs::File::open(input) else {
Expand Down Expand Up @@ -169,7 +176,7 @@
let dir_name = input.parent().unwrap().file_name().unwrap();
let input_name = input.file_name().unwrap();
let crashline = report.crashline;
let crashline = crashline.split('/').last().unwrap();
let crashline = crashline.split('/').next_back().unwrap();
let crashline = crashline.replace(':', "_");

// Copy input
Expand Down Expand Up @@ -281,6 +288,16 @@
.action(ArgAction::SetTrue)
.help("Remove output project directory if it exists")
)
.arg(
Arg::new("ld-preload")
.long("ld-preload")
.env("CASR_PRELOAD")
.action(ArgAction::Set)
.num_args(1..)
.value_name("LIBS")
.value_parser(clap::value_parser!(String))
.help("Set LD_PRELOAD for the target program without disrupting the CASR process itself (both ` ` and `:` are valid delimiter)")
)
.arg(
Arg::new("ARGS")
.action(ArgAction::Set)
Expand Down Expand Up @@ -352,6 +369,9 @@
.build()
.unwrap();

// Get ld preload
let ld_preload = util::get_ld_preload(&matches);

// Set ubsan env options
if let Ok(mut ubsan_options) = env::var("UBSAN_OPTIONS") {
if ubsan_options.starts_with(',') {
Expand Down Expand Up @@ -395,7 +415,8 @@
inputs
.par_iter()
.filter_map(|input| {
let Ok(input_warnings) = extract_warnings(input, &argv, timeout) else {
let Ok(input_warnings) = extract_warnings(input, &argv, timeout, &ld_preload)
else {
warn!("Failed to run program with input file {:?}", input);
*counter.write().unwrap() += 1;
return None;
Expand Down
2 changes: 1 addition & 1 deletion casr/src/triage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ impl<'a> CrashInfo {
/// * `matches` - casr-afl/casr-libfuzzer arguments
///
/// * `crashes` - map of crashes, specified as a HashMap, where
/// key is crash input file name and value is CrashInfo structure
/// key is crash input file name and value is CrashInfo structure
///
/// * `gdb_args` - casr-gdb target arguments. If they are empty, casr-gdb won't be launched.
pub fn fuzzing_crash_triage_pipeline(
Expand Down
18 changes: 18 additions & 0 deletions casr/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ pub fn call_casr_san(matches: &ArgMatches, argv: &[&str], name: &str) -> Result<
if let Some(path) = matches.get_one::<String>("ignore") {
cmd.args(["--ignore", path]);
}
if let Some(ld_preload) = get_ld_preload(matches) {
cmd.args(["--ld-preload", &ld_preload]);
}
cmd.arg("--").args(argv);

let output = cmd
Expand Down Expand Up @@ -614,3 +617,18 @@ pub fn strip_paths(report: &mut CrashReport, stacktrace: &Stacktrace, prefix: &s
.join(" ");
}
}

/// Get LD_PRELOAD
///
/// # Arguments
///
/// * `matches` - casr options
pub fn get_ld_preload(matches: &ArgMatches) -> Option<String> {
let ld_preload = matches.get_many::<String>("ld-preload")?;
Some(
ld_preload
.map(|s| s.to_string())
.collect::<Vec<_>>()
.join(":"),
)
}
Loading
Loading