Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[casr-afl][casr-libfuzzer] Add hints #230

Merged
merged 10 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from 8 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
4 changes: 2 additions & 2 deletions .github/workflows/coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
- name: Build and Run Tests
env:
CARGO_INCREMENTAL: 0
RUSTFLAGS: '-Cinstrument-coverage -Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort'
RUSTFLAGS: '-Cinstrument-coverage -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort'
RUSTDOCFLAGS: '-Cpanic=abort'
LLVM_PROFILE_FILE: 'casr-%p-%m.profraw'
run: |
Expand All @@ -61,6 +61,6 @@ jobs:
--excl-stop '^}$' \
-t lcov
- name: Upload Coverage Reports to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
3 changes: 2 additions & 1 deletion .github/workflows/riscv64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ jobs:
install: |
export CARGO_TERM_COLOR=always
export CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
apt-get update && apt-get install -y gdb pip curl python3.10-dev clang llvm build-essential
apt-get update \
&& apt-get install -y gdb pip curl python3-dev clang llvm build-essential
curl https://sh.rustup.rs -o rustup.sh && chmod +x rustup.sh && \
./rustup.sh -y && rm rustup.sh
run: |
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[![Crates.io](https://img.shields.io/crates/v/casr)](https://crates.io/crates/casr)
[![Documentation](https://docs.rs/libcasr/badge.svg)](https://docs.rs/libcasr)
[![codecov](https://codecov.io/github/ispras/casr/graph/badge.svg?token=D9VY1WRWA7)](https://codecov.io/github/ispras/casr)
SweetVishnya marked this conversation as resolved.
Show resolved Hide resolved
[![codecov](https://app.codecov.io/github/ispras/casr/graph/badge.svg?token=D9VY1WRWA7)](https://codecov.io/github/ispras/casr)
[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://github.com/ispras/casr/blob/master/LICENSE)

[![amd64](https://github.com/ispras/casr/actions/workflows/amd64.yml/badge.svg?branch=master)](https://github.com/ispras/casr/actions/workflows/amd64.yml)
Expand Down
21 changes: 17 additions & 4 deletions casr/src/bin/casr-afl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,15 @@ fn main() -> Result<()> {
.long("no-cluster")
.help("Do not cluster CASR reports")
)
.arg(
Arg::new("hint")
.long("hint")
.value_name("HINT")
.action(ArgAction::Set)
.default_value("auto")
.value_parser(["auto", "gdb", "san", "csharp"])
.help("Hint to force analysis tool")
)
.arg(
Arg::new("ARGS")
.action(ArgAction::Set)
Expand All @@ -129,6 +138,8 @@ fn main() -> Result<()> {
bail!("ARGS is empty, but \"ignore-cmdline\" option is provided.");
}

let hint = matches.get_one::<String>("hint").unwrap();

// Get all crashes.
let mut crashes: HashMap<String, CrashInfo> = HashMap::new();
for node_dir in fs::read_dir(matches.get_one::<PathBuf>("input").unwrap())? {
Expand All @@ -152,9 +163,11 @@ fn main() -> Result<()> {
continue;
}
};
crash_info.casr_tool = if !crash_info.target_args.is_empty()
&& (crash_info.target_args[0].ends_with("dotnet")
|| crash_info.target_args[0].ends_with("mono"))
crash_info.casr_tool = if hint == "csharp"
|| hint == "auto"
&& !crash_info.target_args.is_empty()
&& (crash_info.target_args[0].ends_with("dotnet")
|| crash_info.target_args[0].ends_with("mono"))
{
is_casr_gdb = false;
util::get_path("casr-csharp")?
Expand All @@ -169,7 +182,7 @@ fn main() -> Result<()> {
.map(|x| x + 1);

// When we triage crashes for binaries, use casr-san.
if is_casr_gdb {
if hint == "san" || hint == "auto" && is_casr_gdb {
if let Some(target) = crash_info.target_args.first() {
match util::symbols_list(Path::new(target)) {
Ok(list) => {
Expand Down
2 changes: 1 addition & 1 deletion casr/src/bin/casr-cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
));

if !report.package.is_empty() && !report.package_version.is_empty() {
header_string.append(&format!(
header_string.append(format!(

Check warning on line 156 in casr/src/bin/casr-cli.rs

View check run for this annotation

Codecov / codecov/patch

casr/src/bin/casr-cli.rs#L156

Added line #L156 was not covered by tests
" from {} {}",
report.package, report.package_version
));
Expand Down
25 changes: 21 additions & 4 deletions casr/src/bin/casr-libfuzzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,15 @@ fn main() -> Result<()> {
.action(ArgAction::Set)
.help("Add \"--casr-gdb-args \'./gdb_fuzz_target <arguments>\'\" to generate additional crash reports with casr-gdb (e.g., test whether program crashes without sanitizers)"),
)
.arg(
Arg::new("hint")
.long("hint")
.value_name("HINT")
.action(ArgAction::Set)
.default_value("auto")
.value_parser(["auto", "gdb", "java", "js", "python", "san"])
.help("Hint to force analysis tool")
SweetVishnya marked this conversation as resolved.
Show resolved Hide resolved
)
.arg(
Arg::new("ARGS")
.action(ArgAction::Set)
Expand Down Expand Up @@ -132,22 +141,30 @@ fn main() -> Result<()> {
Vec::new()
};

// Get hint
let hint = matches.get_one::<String>("hint").unwrap();

// Get tool.
let mut envs = HashMap::new();
let tool = if argv[0].ends_with(".py") {
let tool = if hint == "python" || hint == "auto" && argv[0].ends_with(".py") {
envs.insert("LD_PRELOAD".to_string(), util::get_atheris_lib()?);
"casr-python"
} else if argv[0].ends_with("jazzer") || argv[0].ends_with("java") {
} else if hint == "java"
|| hint == "auto" && (argv[0].ends_with("jazzer") || argv[0].ends_with("java"))
{
"casr-java"
} else if argv[0].ends_with(".js")
} else if hint == "js"
|| hint == "auto" && argv[0].ends_with(".js")
SweetVishnya marked this conversation as resolved.
Show resolved Hide resolved
|| argv[0].ends_with("node")
|| argv.len() > 1 && argv[0].ends_with("npx") && argv[1] == "jazzer"
|| argv[0].ends_with("jsfuzz")
{
"casr-js"
} else {
let sym_list = util::symbols_list(Path::new(argv[0]))?;
if sym_list.contains("__asan") || sym_list.contains("runtime.go") {
if hint == "san"
|| hint == "auto" && (sym_list.contains("__asan") || sym_list.contains("runtime.go"))
{
"casr-san"
} else {
"casr-gdb"
Expand Down
2 changes: 1 addition & 1 deletion casr/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@
bail!("Failed to create dir {}", &casrep_dir.to_str().unwrap());
}
} else if !output_dir.exists() && fs::create_dir_all(output_dir).is_err() {
format!("Couldn't create output directory {}", output_dir.display());
bail!("Couldn't create output directory {}", output_dir.display());

Check warning on line 337 in casr/src/util.rs

View check run for this annotation

Codecov / codecov/patch

casr/src/util.rs#L337

Added line #L337 was not covered by tests
}

// Get oom dir
Expand Down
5 changes: 5 additions & 0 deletions casr/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4683,6 +4683,7 @@ fn test_casr_python_call_san_df() {
let work_dir = abs_path("tests/casr_tests/python");
let test_dir = abs_path("tests/tmp_tests_casr/test_casr_python_call_san_df");

let _ = std::fs::remove_dir_all(&test_dir);
let _ = copy_dir(work_dir, &test_dir).unwrap();

let paths = [
Expand Down Expand Up @@ -5924,6 +5925,8 @@ fn test_casr_afl_csharp() {
];

let _ = fs::remove_dir_all(&paths[1]);
let _ = fs::remove_dir_all(&paths[4]);
let _ = fs::remove_dir_all(&paths[5]);
let _ = fs::create_dir(abs_path("tests/tmp_tests_casr"));
let _ = copy_dir(&paths[2], &paths[4]).unwrap();
let _ = copy_dir(&paths[3], &paths[5]).unwrap();
Expand Down Expand Up @@ -6024,6 +6027,8 @@ fn test_casr_afl_csharp_ignore_cmd() {
];

let _ = fs::remove_dir_all(&paths[1]);
let _ = fs::remove_dir_all(&paths[4]);
let _ = fs::remove_dir_all(&paths[5]);
let _ = fs::create_dir(abs_path("tests/tmp_tests_casr"));
let _ = copy_dir(&paths[2], &paths[4]).unwrap();
let _ = copy_dir(&paths[3], &paths[5]).unwrap();
Expand Down
5 changes: 5 additions & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,8 @@ Triage crashes found by AFL++/Sharpfuzz
--ignore-cmdline Force <ARGS> usage to run target instead of searching
for cmdline files in AFL fuzzing directory
--no-cluster Do not cluster CASR reports
--hint <HINT> Hint to force analysis tool [default: auto] [possible
values: auto, gdb, san, csharp]
-h, --help Print help
-V, --version Print version

Expand Down Expand Up @@ -603,6 +605,9 @@ Triage crashes found by libFuzzer based fuzzer
Add "--casr-gdb-args './gdb_fuzz_target <arguments>'" to generate additional
crash reports with casr-gdb (e.g., test whether program crashes without
sanitizers)
--hint <HINT>
Hint to force analysis tool [default: auto] [possible values: auto, gdb, java,
js, python, san]
-h, --help
Print help
-V, --version
Expand Down
8 changes: 2 additions & 6 deletions libcasr/src/cluster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,16 +197,12 @@ impl Cluster {
/// NOTE: Result also can be interpreted as diameter of cluster merge result
pub fn dist_rep(cluster: &Cluster, report: &ReportInfo) -> f64 {
let (_, (trace, _)) = report;
if let Some(max) = cluster
cluster
.stacktraces()
.iter()
.map(|s| 1.0 - similarity(s, trace))
.max_by(|a, b| a.total_cmp(b))
{
max
} else {
0f64
}
.unwrap_or(0f64)
}
}

Expand Down
Loading