From 096fc4f9436a7261996ba4beee79785fb3be8f88 Mon Sep 17 00:00:00 2001 From: desbma Date: Thu, 30 Jan 2025 18:49:08 +0100 Subject: [PATCH] fix: open on symlink path --- src/strace/mod.rs | 32 ++++++++++-- src/strace/parser/combinator.rs | 13 +---- src/strace/parser/mod.rs | 91 +++++++++++++++++++++------------ src/summarize/handlers.rs | 40 ++++++++++++--- src/summarize/mod.rs | 10 +++- 5 files changed, 132 insertions(+), 54 deletions(-) diff --git a/src/strace/mod.rs b/src/strace/mod.rs index c5cf15b..7547735 100644 --- a/src/strace/mod.rs +++ b/src/strace/mod.rs @@ -13,7 +13,7 @@ pub(crate) struct Syscall { pub rel_ts: f64, pub name: String, pub args: Vec, - pub ret_val: SyscallRetVal, + pub ret_val: IntegerExpression, } #[derive(Debug, Clone, PartialEq)] @@ -28,6 +28,12 @@ pub(crate) struct IntegerExpression { pub metadata: Option>, } +impl IntegerExpression { + pub(crate) fn value(&self) -> Option { + self.value.value() + } +} + #[derive(Debug, Clone, PartialEq)] pub(crate) struct BufferExpression { pub value: Vec, @@ -93,9 +99,29 @@ impl IntegerExpressionValue { _ => vec![], } } -} -pub(crate) type SyscallRetVal = i128; // allows holding both signed and unsigned 64 bit integers + pub(crate) fn value(&self) -> Option { + match self { + IntegerExpressionValue::BinaryOr(values) => values + .iter() + .map(Self::value) + .collect::>>()? + .into_iter() + .reduce(|a, b| a | b), + IntegerExpressionValue::Multiplication(values) => values + .iter() + .map(Self::value) + .collect::>>()? + .into_iter() + .reduce(|a, b| a * b), + IntegerExpressionValue::LeftBitShift { bits, shift } => { + Some(bits.value()? << shift.value()?) + } + IntegerExpressionValue::NamedConst(_) => None, + IntegerExpressionValue::Literal(v) => Some(*v), + } + } +} #[derive(Ord, PartialOrd, Eq, PartialEq)] pub(crate) struct StraceVersion { diff --git a/src/strace/parser/combinator.rs b/src/strace/parser/combinator.rs index 5af24a1..5fbf276 100644 --- a/src/strace/parser/combinator.rs +++ b/src/strace/parser/combinator.rs @@ -158,18 +158,9 @@ fn parse_in_out_argument(i: &str) -> IResult<&str, Expression> { } #[function_name::named] -fn parse_ret_val(i: &str) -> IResult<&str, i128> { +fn parse_ret_val(i: &str) -> IResult<&str, IntegerExpression> { dbg_parser!(i); - map_res( - preceded(terminated(char('='), space1), parse_int_literal), - |e| { - if let IntegerExpressionValue::Literal(v) = e.value { - Ok(v) - } else { - Err("Failed to get return value: {e:?}") - } - }, - )(i) + preceded(terminated(char('='), space1), parse_int_literal)(i) } // Shared parsers diff --git a/src/strace/parser/mod.rs b/src/strace/parser/mod.rs index 949efcb..1830e08 100644 --- a/src/strace/parser/mod.rs +++ b/src/strace/parser/mod.rs @@ -11,7 +11,7 @@ use crate::strace::Syscall; mod combinator; use combinator::parse_line; -use super::{Expression, SyscallRetVal}; +use super::{Expression, IntegerExpression}; pub(crate) struct LogParser { reader: Box, @@ -69,7 +69,7 @@ impl SyscallStart { rel_ts: end.rel_ts, name: self.name, args: self.args, - ret_val: end.ret_val, + ret_val: end.ret_val.clone(), } } } @@ -80,7 +80,7 @@ pub(crate) struct SyscallEnd { pub pid: u32, pub rel_ts: f64, pub name: String, - pub ret_val: SyscallRetVal, + pub ret_val: IntegerExpression, } impl Iterator for LogParser { @@ -206,7 +206,7 @@ mod tests { }), ], - ret_val: 0x7f52a332e000 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(0x7f52a332e000), metadata: None } }) ); @@ -251,7 +251,7 @@ mod tests { metadata: None }), ], - ret_val: 0x7f2fce8dc000 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(0x7f2fce8dc000), metadata: None } }) ); } @@ -278,7 +278,7 @@ mod tests { metadata: None, }), ], - ret_val: -1 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(-1), metadata: None } }) ); } @@ -358,7 +358,7 @@ mod tests { metadata: None }), ], - ret_val: 0 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(0), metadata: None } }) ); } @@ -431,7 +431,7 @@ mod tests { metadata: None, }), ], - ret_val: 0, + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(0), metadata: None } }) ); } @@ -581,7 +581,7 @@ mod tests { metadata: None }), ], - ret_val: 0 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(0), metadata: None } }) ); } @@ -612,7 +612,7 @@ mod tests { metadata: None, }), ], - ret_val: 8 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(8), metadata: None } }) ); } @@ -737,7 +737,7 @@ mod tests { ), ])) ], - ret_val: 0 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(0), metadata: None } }) ); @@ -860,7 +860,7 @@ mod tests { ), ])) ], - ret_val: 0 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(0), metadata: None } }) ); } @@ -896,7 +896,10 @@ mod tests { metadata: None, }), ], - ret_val: 3 + ret_val: IntegerExpression { + value: IntegerExpressionValue::Literal(3), + metadata: Some("/home/mde/src".as_bytes().to_vec()) + } }) ); } @@ -1014,7 +1017,7 @@ mod tests { metadata: None, }), ], - ret_val: 20 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(20), metadata: None } }) ); @@ -1038,7 +1041,10 @@ mod tests { metadata: None, }), ], - ret_val: 832 + ret_val: IntegerExpression { + value: IntegerExpressionValue::Literal(832), + metadata: None + } }) ); } @@ -1093,7 +1099,7 @@ mod tests { metadata: None, }), ], - ret_val: 0 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(0), metadata: None } }) ); @@ -1148,7 +1154,7 @@ mod tests { metadata: None, }), ], - ret_val: 0 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(0), metadata: None } }) ); } @@ -1201,7 +1207,7 @@ mod tests { metadata: None, }), ], - ret_val: 0 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(0), metadata: None } }) ); } @@ -1260,7 +1266,7 @@ mod tests { ), ])), ], - ret_val: 0 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(0), metadata: None } }) ); @@ -1361,7 +1367,7 @@ mod tests { metadata: None, }), ], - ret_val: 2 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(2), metadata: None } }) ); } @@ -1409,7 +1415,10 @@ mod tests { ), ])), ], - ret_val: 0 + ret_val: IntegerExpression { + value: IntegerExpressionValue::Literal(0), + metadata: None + } }, Syscall { pid: 1, @@ -1443,7 +1452,10 @@ mod tests { metadata: None, }), ], - ret_val: 1 + ret_val: IntegerExpression { + value: IntegerExpressionValue::Literal(1), + metadata: None + } } ] ); @@ -1460,7 +1472,10 @@ mod tests { rel_ts: 0.000022, name: "getpid".to_owned(), args: vec![], - ret_val: 641314 + ret_val: IntegerExpression { + value: IntegerExpressionValue::Literal(641314), + metadata: None + } }) ); } @@ -1481,7 +1496,7 @@ mod tests { metadata: Some("/memfd:mozilla-ipc".as_bytes().to_vec()), }), ], - ret_val: 0 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(0), metadata: None } }) ); } @@ -1568,7 +1583,10 @@ mod tests { ] }, ], - ret_val: 8 + ret_val: IntegerExpression { + value: IntegerExpressionValue::Literal(8), + metadata: None + } }) ); } @@ -1610,7 +1628,10 @@ mod tests { ),] }, ], - ret_val: 0 + ret_val: IntegerExpression { + value: IntegerExpressionValue::Literal(0), + metadata: None + } }) ); } @@ -2122,7 +2143,7 @@ mod tests { ), ])) ], - ret_val: 0 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(0), metadata: None } }) ); } @@ -2207,7 +2228,10 @@ mod tests { metadata: None, }), ], - ret_val: 664773 + ret_val: IntegerExpression { + value: IntegerExpressionValue::Literal(664773), + metadata: None + } }) ); @@ -2246,7 +2270,7 @@ mod tests { metadata: None, }), ], - ret_val: 0 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(0), metadata: None } }) ); } @@ -2293,7 +2317,10 @@ mod tests { ), ])), ], - ret_val: 714434 + ret_val: IntegerExpression { + value: IntegerExpressionValue::Literal(714434), + metadata: None + } }) ); } @@ -2358,7 +2385,7 @@ mod tests { ), ])), ], - ret_val: 0 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(0), metadata: None } }) ); } @@ -2443,7 +2470,7 @@ mod tests { metadata: None, }), ], - ret_val: 0 + ret_val: IntegerExpression { value: IntegerExpressionValue::Literal(0), metadata: None } }) ); } diff --git a/src/summarize/handlers.rs b/src/summarize/handlers.rs index 6e8965e..be58d1a 100644 --- a/src/summarize/handlers.rs +++ b/src/summarize/handlers.rs @@ -62,7 +62,7 @@ pub(crate) fn summarize_syscall( handle_network(&sc.name, sc.pid, fd, sockaddr, actions, state) } SyscallArgsInfo::Open { relfd, path, flags } => { - handle_open(&sc.name, relfd, path, flags, actions, state) + handle_open(&sc.name, relfd, path, flags, &sc.ret_val, actions, state) } SyscallArgsInfo::Rename { relfd_src, @@ -75,7 +75,7 @@ pub(crate) fn summarize_syscall( ), SyscallArgsInfo::SetScheduler { policy } => handle_setscheduler(&sc.name, policy, actions), SyscallArgsInfo::Socket { af, flags } => { - handle_socket(&sc.name, sc.pid, sc.ret_val, af, flags, actions, state) + handle_socket(&sc.name, sc.pid, &sc.ret_val, af, flags, actions, state) } SyscallArgsInfo::StatFd { fd } => handle_stat_fd(&sc.name, fd, actions, state), SyscallArgsInfo::StatPath { relfd, path } => { @@ -375,6 +375,7 @@ fn handle_open( relfd: Option<&Expression>, path: &Expression, flags: &Expression, + ret_val: &IntegerExpression, actions: &mut Vec, state: &ProgramState, ) -> Result<(), HandlerError> { @@ -405,9 +406,19 @@ fn handle_open( } else { return Ok(()); }; + let ret_path = ret_val + .metadata + .as_ref() + .map(|b| PathBuf::from(OsStr::from_bytes(b))); if flags_val.is_flag_set("O_CREAT") { actions.push(ProgramAction::Create(path.clone())); + if let Some(ret_path) = &ret_path { + // Add path from returned fd (can be different because symlinks are followed) + if *ret_path != path { + actions.push(ProgramAction::Create(ret_path.clone())); + } + } } if (flags_val.is_flag_set("O_WRONLY") || flags_val.is_flag_set("O_RDWR") @@ -416,9 +427,21 @@ fn handle_open( && !path.metadata().ok().is_some_and(|m| m.file_type().is_char_device()) { actions.push(ProgramAction::Write(path.clone())); + if let Some(ret_path) = &ret_path { + // Add path from returned fd (can be different because symlinks are followed) + if *ret_path != path { + actions.push(ProgramAction::Write(ret_path.clone())); + } + } } if flags_val.is_flag_set("O_RDONLY") || !flags_val.is_flag_set("O_WRONLY") { - actions.push(ProgramAction::Read(path)); + actions.push(ProgramAction::Read(path.clone())); + if let Some(ret_path) = ret_path { + // Add path from returned fd (can be different because symlinks are followed) + if ret_path != path { + actions.push(ProgramAction::Read(ret_path)); + } + } } Ok(()) } @@ -517,7 +540,7 @@ fn handle_setscheduler( fn handle_socket( name: &str, pid: u32, - ret_val: i128, + ret_val: &IntegerExpression, af: &Expression, flags: &Expression, actions: &mut Vec, @@ -560,11 +583,16 @@ fn handle_socket( src: proto_flag.to_owned(), type_: type_name::(), })?; + let ret_fd = ret_val.value().ok_or_else(|| HandlerError::ParsingFailed { + src: format!("{ret_val:?}"), + type_: type_name::(), + })?; + state.known_sockets_proto.insert( ( pid, - TryInto::::try_into(ret_val).map_err(|_| HandlerError::ConversionFailed { - src: ret_val.to_string(), + TryInto::::try_into(ret_fd).map_err(|_| HandlerError::ConversionFailed { + src: ret_fd.to_string(), type_src: type_name_of_val(&ret_val), type_dst: type_name::(), })?, diff --git a/src/summarize/mod.rs b/src/summarize/mod.rs index 777447b..0a31c34 100644 --- a/src/summarize/mod.rs +++ b/src/summarize/mod.rs @@ -689,7 +689,10 @@ mod tests { metadata: None, }), ], - ret_val: 0, + ret_val: IntegerExpression { + value: IntegerExpressionValue::Literal(0), + metadata: None, + }, })]; assert_eq!( summarize(syscalls).unwrap(), @@ -737,7 +740,10 @@ mod tests { metadata: None, }), ], - ret_val: 0, + ret_val: IntegerExpression { + value: IntegerExpressionValue::Literal(0), + metadata: None, + }, })]; assert_eq!( summarize(syscalls).unwrap(),