diff --git a/casr/src/bin/casr-cluster.rs b/casr/src/bin/casr-cluster.rs index a4a903bf..66bffa3c 100644 --- a/casr/src/bin/casr-cluster.rs +++ b/casr/src/bin/casr-cluster.rs @@ -1,7 +1,5 @@ use casr::util; -use libcasr::constants::*; -use libcasr::init_ignored_frames; -use libcasr::stacktrace::*; +use libcasr::{init_ignored_frames, stacktrace::*}; use anyhow::{bail, Context, Result}; use clap::{Arg, ArgAction}; diff --git a/casr/src/bin/casr-dojo.rs b/casr/src/bin/casr-dojo.rs index 77227ebe..7742c7dd 100644 --- a/casr/src/bin/casr-dojo.rs +++ b/casr/src/bin/casr-dojo.rs @@ -1,8 +1,5 @@ use casr::util; -use libcasr::constants::*; -use libcasr::init_ignored_frames; -use libcasr::report::CrashReport; -use libcasr::stacktrace::*; +use libcasr::{init_ignored_frames, report::CrashReport, stacktrace::*}; use anyhow::{bail, Result}; use clap::error::{ContextKind, ContextValue, ErrorKind}; diff --git a/casr/src/bin/casr-gdb.rs b/casr/src/bin/casr-gdb.rs index 5befc064..2b62eb41 100644 --- a/casr/src/bin/casr-gdb.rs +++ b/casr/src/bin/casr-gdb.rs @@ -1,14 +1,15 @@ use casr::util; -use libcasr::constants::*; -use libcasr::cpp::CppException; -use libcasr::exception::Exception; -use libcasr::gdb::exploitable::{GdbContext, MachineInfo}; -use libcasr::gdb::GdbStacktrace; -use libcasr::init_ignored_frames; -use libcasr::report::CrashReport; -use libcasr::rust::RustPanic; -use libcasr::severity::Severity; -use libcasr::stacktrace::*; +use libcasr::{ + cpp::CppException, + exception::Exception, + gdb::exploitable::{GdbContext, MachineInfo}, + gdb::GdbStacktrace, + init_ignored_frames, + report::CrashReport, + rust::RustPanic, + severity::Severity, + stacktrace::*, +}; use anyhow::{bail, Context, Result}; use clap::{Arg, ArgAction, ArgGroup}; diff --git a/casr/src/bin/casr-java.rs b/casr/src/bin/casr-java.rs index 0fe1c08b..b5aa0658 100644 --- a/casr/src/bin/casr-java.rs +++ b/casr/src/bin/casr-java.rs @@ -1,10 +1,7 @@ use casr::util; -use libcasr::constants::*; -use libcasr::exception::Exception; -use libcasr::init_ignored_frames; -use libcasr::java::*; -use libcasr::report::CrashReport; -use libcasr::stacktrace::*; +use libcasr::{ + exception::Exception, init_ignored_frames, java::*, report::CrashReport, stacktrace::*, +}; use anyhow::{bail, Result}; use clap::{Arg, ArgAction, ArgGroup}; diff --git a/casr/src/bin/casr-python.rs b/casr/src/bin/casr-python.rs index a69ecbf5..26be758b 100644 --- a/casr/src/bin/casr-python.rs +++ b/casr/src/bin/casr-python.rs @@ -1,10 +1,11 @@ use casr::util; -use libcasr::constants::*; -use libcasr::exception::Exception; -use libcasr::init_ignored_frames; -use libcasr::python::{PythonException, PythonStacktrace}; -use libcasr::report::CrashReport; -use libcasr::stacktrace::*; +use libcasr::{ + exception::Exception, + init_ignored_frames, + python::{PythonException, PythonStacktrace}, + report::CrashReport, + stacktrace::*, +}; use anyhow::{bail, Result}; use clap::{Arg, ArgAction, ArgGroup}; diff --git a/casr/src/bin/casr-san.rs b/casr/src/bin/casr-san.rs index 9c0a1f5c..c2b338a5 100644 --- a/casr/src/bin/casr-san.rs +++ b/casr/src/bin/casr-san.rs @@ -1,16 +1,21 @@ use casr::util; -use libcasr::asan::{AsanContext, AsanStacktrace}; -use libcasr::constants::*; -use libcasr::cpp::CppException; -use libcasr::exception::Exception; -use libcasr::execution_class::*; -use libcasr::gdb::*; -use libcasr::go::*; -use libcasr::init_ignored_frames; -use libcasr::report::CrashReport; -use libcasr::rust::{RustPanic, RustStacktrace}; -use libcasr::severity::Severity; -use libcasr::stacktrace::*; +use libcasr::{ + asan::{AsanContext, AsanStacktrace}, + constants::{ + SIGINFO_SIGABRT, SIGINFO_SIGBUS, SIGINFO_SIGILL, SIGINFO_SIGSEGV, SIGINFO_SIGSYS, + SIGINFO_SIGTRAP, + }, + cpp::CppException, + exception::Exception, + execution_class::*, + gdb::*, + go::*, + init_ignored_frames, + report::CrashReport, + rust::{RustPanic, RustStacktrace}, + severity::Severity, + stacktrace::*, +}; use anyhow::{bail, Context, Result}; use clap::{Arg, ArgAction, ArgGroup}; diff --git a/libcasr/fuzz/fuzz_targets/parse_stacktrace.rs b/libcasr/fuzz/fuzz_targets/parse_stacktrace.rs index 9e04a362..c0b42c9b 100644 --- a/libcasr/fuzz/fuzz_targets/parse_stacktrace.rs +++ b/libcasr/fuzz/fuzz_targets/parse_stacktrace.rs @@ -4,22 +4,12 @@ use libfuzzer_sys::fuzz_target; use libcasr::{ asan::AsanStacktrace, - constants::{ - STACK_FRAME_FILEPATH_IGNORE_REGEXES_CPP, STACK_FRAME_FILEPATH_IGNORE_REGEXES_GO, - STACK_FRAME_FILEPATH_IGNORE_REGEXES_JAVA, STACK_FRAME_FILEPATH_IGNORE_REGEXES_PYTHON, - STACK_FRAME_FILEPATH_IGNORE_REGEXES_RUST, STACK_FRAME_FUNCTION_IGNORE_REGEXES_CPP, - STACK_FRAME_FUNCTION_IGNORE_REGEXES_GO, STACK_FRAME_FUNCTION_IGNORE_REGEXES_JAVA, - STACK_FRAME_FUNCTION_IGNORE_REGEXES_PYTHON, STACK_FRAME_FUNCTION_IGNORE_REGEXES_RUST, - }, gdb::GdbStacktrace, go::GoStacktrace, init_ignored_frames, java::JavaStacktrace, python::PythonStacktrace, - stacktrace::{ - CrashLineExt, ParseStacktrace, STACK_FRAME_FILEPATH_IGNORE_REGEXES, - STACK_FRAME_FUNCTION_IGNORE_REGEXES, - }, + stacktrace::{CrashLineExt, Filter, ParseStacktrace, Stacktrace}, }; fuzz_target!(|data: &[u8]| { diff --git a/libcasr/src/rust.rs b/libcasr/src/rust.rs index 3c4142b6..eb3dc6eb 100644 --- a/libcasr/src/rust.rs +++ b/libcasr/src/rust.rs @@ -108,17 +108,8 @@ mod tests { use super::*; use crate::{ - constants::{ - STACK_FRAME_FILEPATH_IGNORE_REGEXES_CPP, STACK_FRAME_FILEPATH_IGNORE_REGEXES_GO, - STACK_FRAME_FILEPATH_IGNORE_REGEXES_JAVA, STACK_FRAME_FILEPATH_IGNORE_REGEXES_PYTHON, - STACK_FRAME_FILEPATH_IGNORE_REGEXES_RUST, STACK_FRAME_FUNCTION_IGNORE_REGEXES_CPP, - STACK_FRAME_FUNCTION_IGNORE_REGEXES_GO, STACK_FRAME_FUNCTION_IGNORE_REGEXES_JAVA, - STACK_FRAME_FUNCTION_IGNORE_REGEXES_PYTHON, STACK_FRAME_FUNCTION_IGNORE_REGEXES_RUST, - }, init_ignored_frames, - stacktrace::{ - Filter, STACK_FRAME_FILEPATH_IGNORE_REGEXES, STACK_FRAME_FUNCTION_IGNORE_REGEXES, - }, + stacktrace::{Filter, Stacktrace}, }; #[test] diff --git a/libcasr/src/sarif.rs b/libcasr/src/sarif.rs index aab74f7b..1cca56b3 100644 --- a/libcasr/src/sarif.rs +++ b/libcasr/src/sarif.rs @@ -1,12 +1,13 @@ //! Sarif module contains `Sarif` struct that contains multiple `CrashReport` //! structs in SARIF format. -use crate::constants::*; -use crate::error::{Error, Result}; -use crate::execution_class::{ExecutionClass, CLASSES}; -use crate::init_ignored_frames; -use crate::report::CrashReport; -use crate::stacktrace::{STACK_FRAME_FILEPATH_IGNORE_REGEXES, STACK_FRAME_FUNCTION_IGNORE_REGEXES}; +use crate::{ + error::{Error, Result}, + execution_class::{ExecutionClass, CLASSES}, + init_ignored_frames, + report::CrashReport, + stacktrace::{Filter, Stacktrace}, +}; use serde_json::{Map, Value}; diff --git a/libcasr/src/stacktrace.rs b/libcasr/src/stacktrace.rs index 7c7631b9..b619b54c 100644 --- a/libcasr/src/stacktrace.rs +++ b/libcasr/src/stacktrace.rs @@ -2,6 +2,13 @@ extern crate kodama; extern crate lazy_static; +use crate::constants::{ + STACK_FRAME_FILEPATH_IGNORE_REGEXES_CPP, STACK_FRAME_FILEPATH_IGNORE_REGEXES_GO, + STACK_FRAME_FILEPATH_IGNORE_REGEXES_JAVA, STACK_FRAME_FILEPATH_IGNORE_REGEXES_PYTHON, + STACK_FRAME_FILEPATH_IGNORE_REGEXES_RUST, STACK_FRAME_FUNCTION_IGNORE_REGEXES_CPP, + STACK_FRAME_FUNCTION_IGNORE_REGEXES_GO, STACK_FRAME_FUNCTION_IGNORE_REGEXES_JAVA, + STACK_FRAME_FUNCTION_IGNORE_REGEXES_PYTHON, STACK_FRAME_FUNCTION_IGNORE_REGEXES_RUST, +}; use crate::error::*; use kodama::{linkage, Method}; use regex::Regex; @@ -31,18 +38,7 @@ lazy_static::lazy_static! { macro_rules! init_ignored_frames { ( $( $x:expr ),* ) => { { - let (funcs, files): (Vec<_>, Vec<_>) = [$($x,)*].iter().map(|&x| - match x { - "python" => (STACK_FRAME_FUNCTION_IGNORE_REGEXES_PYTHON, STACK_FRAME_FILEPATH_IGNORE_REGEXES_PYTHON), - "rust" => (STACK_FRAME_FUNCTION_IGNORE_REGEXES_RUST, STACK_FRAME_FILEPATH_IGNORE_REGEXES_RUST), - "cpp" => (STACK_FRAME_FUNCTION_IGNORE_REGEXES_CPP, STACK_FRAME_FILEPATH_IGNORE_REGEXES_CPP), - "go" => (STACK_FRAME_FUNCTION_IGNORE_REGEXES_GO, STACK_FRAME_FILEPATH_IGNORE_REGEXES_GO), - "java" => (STACK_FRAME_FUNCTION_IGNORE_REGEXES_JAVA, STACK_FRAME_FILEPATH_IGNORE_REGEXES_JAVA), - &_ => (["^[^.]$"].as_slice(), ["^[^.]$"].as_slice()), - } - ).unzip(); - *STACK_FRAME_FUNCTION_IGNORE_REGEXES.write().unwrap() = funcs.concat().iter().map(|x| x.to_string()).collect::>(); - *STACK_FRAME_FILEPATH_IGNORE_REGEXES.write().unwrap() = files.concat().iter().map(|x| x.to_string()).collect::>(); + ::init_frame_filter(&[$($x,)*]); } }; } @@ -257,27 +253,77 @@ pub fn cluster_stacktraces(stacktraces: &[Stacktrace]) -> Result> { pub trait Filter { /// Filter frames from the stack trace that are not related to analyzed code containing crash. fn filter(&mut self); + + /// Initialize global variables for stacktrace filtering + /// + /// # Arguments + /// + /// * `languages` - list of program languages for filtering + fn init_frame_filter(languages: &[&str]) { + let (funcs, files): (Vec<_>, Vec<_>) = languages + .iter() + .map(|&x| match x { + "python" => ( + STACK_FRAME_FUNCTION_IGNORE_REGEXES_PYTHON, + STACK_FRAME_FILEPATH_IGNORE_REGEXES_PYTHON, + ), + "rust" => ( + STACK_FRAME_FUNCTION_IGNORE_REGEXES_RUST, + STACK_FRAME_FILEPATH_IGNORE_REGEXES_RUST, + ), + "cpp" => ( + STACK_FRAME_FUNCTION_IGNORE_REGEXES_CPP, + STACK_FRAME_FILEPATH_IGNORE_REGEXES_CPP, + ), + "go" => ( + STACK_FRAME_FUNCTION_IGNORE_REGEXES_GO, + STACK_FRAME_FILEPATH_IGNORE_REGEXES_GO, + ), + "java" => ( + STACK_FRAME_FUNCTION_IGNORE_REGEXES_JAVA, + STACK_FRAME_FILEPATH_IGNORE_REGEXES_JAVA, + ), + &_ => (["^[^.]$"].as_slice(), ["^[^.]$"].as_slice()), + }) + .unzip(); + *STACK_FRAME_FUNCTION_IGNORE_REGEXES.write().unwrap() = funcs + .concat() + .iter() + .map(|x| x.to_string()) + .collect::>(); + *STACK_FRAME_FILEPATH_IGNORE_REGEXES.write().unwrap() = files + .concat() + .iter() + .map(|x| x.to_string()) + .collect::>(); + } } impl Filter for Stacktrace { fn filter(&mut self) { // Compile function regexp. - let rstring = STACK_FRAME_FUNCTION_IGNORE_REGEXES - .read() - .unwrap() - .iter() - .map(|s| format!("({s})|")) - .collect::(); - let rfunction = Regex::new(&rstring[0..rstring.len() - 1]).unwrap(); + let function_regexes = STACK_FRAME_FUNCTION_IGNORE_REGEXES.read().unwrap(); + let rfunction = if !function_regexes.is_empty() { + let rstring = function_regexes + .iter() + .map(|s| format!("({s})|")) + .collect::(); + Regex::new(&rstring[0..rstring.len() - 1]).unwrap() + } else { + Regex::new(r"^[^.]$").unwrap() + }; // Compile file regexp. - let rstring = STACK_FRAME_FILEPATH_IGNORE_REGEXES - .read() - .unwrap() - .iter() - .map(|s| format!("({s})|")) - .collect::(); - let rfile = Regex::new(&rstring[0..rstring.len() - 1]).unwrap(); + let file_regexes = STACK_FRAME_FILEPATH_IGNORE_REGEXES.read().unwrap(); + let rfile = if !file_regexes.is_empty() { + let rstring = file_regexes + .iter() + .map(|s| format!("({s})|")) + .collect::(); + Regex::new(&rstring[0..rstring.len() - 1]).unwrap() + } else { + Regex::new(r"^[^.]$").unwrap() + }; // For libfuzzer: delete functions below LLVMFuzzerTestOneInput if let Some(pos) = &self