diff --git a/changelog/2653.fixed.md b/changelog/2653.fixed.md new file mode 100644 index 0000000000..fb2885671d --- /dev/null +++ b/changelog/2653.fixed.md @@ -0,0 +1 @@ +Fixed `nix::sys::ptrace::syscall_info`, which was not setting the `data` argument properly, causing garbage values to be returned. diff --git a/examples/ptrace.rs b/examples/ptrace.rs new file mode 100644 index 0000000000..32cb22f0b0 --- /dev/null +++ b/examples/ptrace.rs @@ -0,0 +1,39 @@ +//! Traces a child process using `ptrace`. +//! +//! The child issues a single `write` syscall, which is printed upon entry and exit. + +#[cfg(all(target_os = "linux", target_env = "gnu"))] +fn main() { + let pid = unsafe { nix::unistd::fork().unwrap() }; + + match pid { + nix::unistd::ForkResult::Child => { + nix::sys::ptrace::traceme().unwrap(); + nix::sys::signal::raise(nix::sys::signal::Signal::SIGCONT).unwrap(); + println!("I'm issuing a syscall!"); + } + nix::unistd::ForkResult::Parent { child } => { + nix::sys::wait::waitpid(Some(child), None).unwrap(); + nix::sys::ptrace::setoptions( + child, + nix::sys::ptrace::Options::PTRACE_O_TRACESYSGOOD, + ) + .unwrap(); + + nix::sys::ptrace::syscall(child, None).unwrap(); + nix::sys::wait::waitpid(Some(child), None).unwrap(); + let syscall_info = nix::sys::ptrace::syscall_info(child).unwrap(); + println!("{syscall_info:?}"); + assert!(syscall_info.op == libc::PTRACE_SYSCALL_INFO_ENTRY); + + nix::sys::ptrace::syscall(child, None).unwrap(); + nix::sys::wait::waitpid(Some(child), None).unwrap(); + let syscall_info = nix::sys::ptrace::syscall_info(child).unwrap(); + println!("{syscall_info:?}"); + assert!(syscall_info.op == libc::PTRACE_SYSCALL_INFO_EXIT); + } + } +} + +#[cfg(not(all(target_os = "linux", target_env = "gnu")))] +fn main() {} diff --git a/src/sys/ptrace/linux.rs b/src/sys/ptrace/linux.rs index 8c1a46ba8d..d067ef5789 100644 --- a/src/sys/ptrace/linux.rs +++ b/src/sys/ptrace/linux.rs @@ -504,7 +504,7 @@ fn ptrace_get_data(request: Request, pid: Pid) -> Result { libc::ptrace( request as RequestType, libc::pid_t::from(pid), - ptr::null_mut::(), + std::mem::size_of::(), data.as_mut_ptr(), ) };