diff --git a/src/filestore.rs b/src/filestore.rs index 0dfa97b..93b5126 100644 --- a/src/filestore.rs +++ b/src/filestore.rs @@ -1,13 +1,17 @@ use std::{ + borrow::Cow, collections::{BTreeMap, HashMap, HashSet}, fs, io, - path::PathBuf, borrow::Cow, + path::PathBuf, }; use gimli::{constants, DW_TAG_compile_unit}; +use object::{Object, ObjectSection, ReadCache}; use serde::{Deserialize, Serialize}; -use sha2::{digest::generic_array::{GenericArray, typenum::U32}, Digest, Sha256}; -use object::{Object, ReadCache, ObjectSection}; +use sha2::{ + digest::generic_array::{typenum::U32, GenericArray}, + Digest, Sha256, +}; use typed_arena::Arena; #[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] @@ -20,7 +24,7 @@ pub struct Sha256Hash { impl From> for Sha256Hash { fn from(value: GenericArray) -> Self { Self { - inner: value.into() + inner: value.into(), } } } @@ -43,9 +47,7 @@ pub struct FileStoreEntry { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum FileFormat { - ELF { - references: Vec, - }, + ELF { references: Vec }, Other, } @@ -116,8 +118,7 @@ impl FileStore { } }; - if index == self.files.len() { - } + if index == self.files.len() {} self.filenames.insert(filename, index); Ok(()) @@ -201,12 +202,16 @@ impl FileStore { if entry.tag() == DW_TAG_compile_unit { let mut basename = None; let mut dirname = None; - if let Some(name) = entry.attr(constants::DW_AT_name)?.map(|a| a.value()) { + if let Some(name) = + entry.attr(constants::DW_AT_name)?.map(|a| a.value()) + { if let Ok(name) = dwarf.attr_string(&dwarf.unit(unit)?, name) { basename = Some(PathBuf::from(name.to_string()?)); } } - if let Some(name) = entry.attr(constants::DW_AT_comp_dir)?.map(|a| a.value()) { + if let Some(name) = + entry.attr(constants::DW_AT_comp_dir)?.map(|a| a.value()) + { if let Ok(name) = dwarf.attr_string(&dwarf.unit(unit)?, name) { dirname = Some(PathBuf::from(name.to_string()?)); } @@ -218,11 +223,15 @@ impl FileStore { } } - let references = inputs.into_iter().map(|input| self.ingest_dependency_local(input)).collect::, _>>()?.into_iter().filter_map(|x| x).collect(); - FileFormat::ELF { - references, - } - }, + let references = inputs + .into_iter() + .map(|input| self.ingest_dependency_local(input)) + .collect::, _>>()? + .into_iter() + .filter_map(|x| x) + .collect(); + FileFormat::ELF { references } + } _ => FileFormat::Other, }) } diff --git a/src/main.rs b/src/main.rs index 34be403..a3eee1b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ -mod tracer; mod filestore; mod reports; +mod tracer; use std::path::PathBuf; @@ -38,16 +38,27 @@ enum Subcommands { /// The filepath to dump the json report to. will dump to stdout if unspecified. output: Option, - } + }, } fn main() { env_logger::init(); let cli = Cli::parse(); match cli.cmd { - Subcommands::Run { file_scope, output, cmd, mute } => { + Subcommands::Run { + file_scope, + output, + cmd, + mute, + } => { let fp: Box = if let Some(output) = &output { - Box::new(std::fs::File::options().write(true).create(true).open(output).unwrap()) + Box::new( + std::fs::File::options() + .write(true) + .create(true) + .open(output) + .unwrap(), + ) } else { Box::new(std::io::stdout()) }; @@ -58,11 +69,18 @@ fn main() { serde_json::to_writer_pretty(fp, &t.report) } else { serde_json::to_writer(fp, &t.report) - }.expect("Could not serialize json trace report"); + } + .expect("Could not serialize json trace report"); } Subcommands::QueryParameters { input, output } => { let fp: Box = if let Some(output) = &output { - Box::new(std::fs::File::options().write(true).create(true).open(output).unwrap()) + Box::new( + std::fs::File::options() + .write(true) + .create(true) + .open(output) + .unwrap(), + ) } else { Box::new(std::io::stdout()) }; @@ -71,7 +89,8 @@ fn main() { serde_json::from_reader(std::fs::File::open(input).unwrap()) } else { serde_json::from_reader(std::io::stdin()) - }.expect("Could not deserialize json trace report"); + } + .expect("Could not deserialize json trace report"); let out_report = reports::parameters::run(&in_report).unwrap(); @@ -79,7 +98,8 @@ fn main() { serde_json::to_writer_pretty(fp, &out_report) } else { serde_json::to_writer(fp, &out_report) - }.expect("Could not serialize json parameter report"); + } + .expect("Could not serialize json parameter report"); } } } diff --git a/src/tracer.rs b/src/tracer.rs index c77813f..1fe905c 100644 --- a/src/tracer.rs +++ b/src/tracer.rs @@ -2,18 +2,18 @@ use std::{ collections::HashMap, ffi::CString, ffi::OsString, - os::{fd::{AsRawFd}, unix::prelude::OsStringExt}, + fmt::{Display, Formatter}, + os::{fd::AsRawFd, unix::prelude::OsStringExt}, path::PathBuf, process::exit, time::{Duration, Instant}, - fmt::{Display, Formatter}, }; use core::fmt; use nix::{ errno::Errno, - libc::{pid_t, raise, tcsetpgrp, AT_EMPTY_PATH, SIGSTOP, STDIN_FILENO, AT_FDCWD}, + libc::{pid_t, raise, tcsetpgrp, AT_EMPTY_PATH, AT_FDCWD, SIGSTOP, STDIN_FILENO}, sys::{ ptrace::{self, traceme, AddressType}, signal::Signal, @@ -446,10 +446,7 @@ impl Tracer { Ok(Self { store: ProcessStateStore::default(), start_time: Instant::now(), - report: TracerReport { - log: vec![], - files, - }, + report: TracerReport { log: vec![], files }, }) } @@ -585,7 +582,14 @@ impl Tracer { // So we need to determine whether exec is successful here. // PTRACE_EVENT_EXEC only happens for successful exec. p.is_exec_successful = true; - let path = p.pending_syscall_event.iter().find_map(|e| match e { Event::Exec { prog, .. } => Some(prog.clone()), _ => None }).unwrap(); + let path = p + .pending_syscall_event + .iter() + .find_map(|e| match e { + Event::Exec { prog, .. } => Some(prog.clone()), + _ => None, + }) + .unwrap(); self.report.files.ingest_output_local(path)?; self.drain_syscall_events(pid.into(), Box::new(|_| {})); // Don't use seccomp_aware_cont here because that will skip the next syscall exit stop @@ -634,10 +638,17 @@ impl Tracer { } if mute { - let null = std::fs::File::options().read(true).write(true).open("/dev/null").expect("Could not open /dev/null"); - nix::unistd::dup2(null.as_raw_fd(), 0).expect("Could not dup /dev/null to /dev/stdin"); - nix::unistd::dup2(null.as_raw_fd(), 1).expect("Could not dup /dev/null to /dev/stdout"); - nix::unistd::dup2(null.as_raw_fd(), 2).expect("Could not dup /dev/null to /dev/stderr"); + let null = std::fs::File::options() + .read(true) + .write(true) + .open("/dev/null") + .expect("Could not open /dev/null"); + nix::unistd::dup2(null.as_raw_fd(), 0) + .expect("Could not dup /dev/null to /dev/stdin"); + nix::unistd::dup2(null.as_raw_fd(), 1) + .expect("Could not dup /dev/null to /dev/stdout"); + nix::unistd::dup2(null.as_raw_fd(), 2) + .expect("Could not dup /dev/null to /dev/stderr"); } let args = args @@ -780,7 +791,11 @@ impl Tracer { nix::libc::SYS_open | nix::libc::SYS_openat => { if result >= 0 { for pending in p.pending_syscall_event.iter_mut() { - if let Event::FdOpen { source: FdSource::File { path }, .. } = pending { + if let Event::FdOpen { + source: FdSource::File { path }, + .. + } = pending + { self.report.files.ingest_output_local(path.clone())?; } }