This commit is contained in:
Audrey 2024-04-17 09:44:17 -07:00
parent 62f7e40c64
commit fbc5634ad9
3 changed files with 81 additions and 37 deletions

View File

@ -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<GenericArray<u8, U32>> for Sha256Hash {
fn from(value: GenericArray<u8, U32>) -> 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<usize>,
},
ELF { references: Vec<usize> },
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::<Result<Vec<_>, _>>()?.into_iter().filter_map(|x| x).collect();
FileFormat::ELF {
references,
}
},
let references = inputs
.into_iter()
.map(|input| self.ingest_dependency_local(input))
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.filter_map(|x| x)
.collect();
FileFormat::ELF { references }
}
_ => FileFormat::Other,
})
}

View File

@ -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<PathBuf>,
}
},
}
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<dyn std::io::Write> = 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<dyn std::io::Write> = 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");
}
}
}

View File

@ -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())?;
}
}