diff --git a/src/sys/ptrace/linux.rs b/src/sys/ptrace/linux.rs index 1e1004b5b2..18c29eb6f2 100644 --- a/src/sys/ptrace/linux.rs +++ b/src/sys/ptrace/linux.rs @@ -126,6 +126,8 @@ libc_enum! { PTRACE_SYSEMU_SINGLESTEP, #[cfg(all(target_os = "linux", target_env = "gnu"))] PTRACE_GET_SYSCALL_INFO, + PTRACE_GETSIGMASK, + PTRACE_SETSIGMASK, } } @@ -325,7 +327,7 @@ fn ptrace_get_data(request: Request, pid: Pid) -> Result { libc::ptrace( request as RequestType, libc::pid_t::from(pid), - ptr::null_mut::(), + mem::size_of::(), data.as_mut_ptr() as *const _ as *const c_void, ) }; @@ -371,6 +373,11 @@ pub fn getsiginfo(pid: Pid) -> Result { ptrace_get_data::(Request::PTRACE_GETSIGINFO, pid) } +/// Get sigmask as with `ptrace(PTRACE_GETSIGMASK,...)` +pub fn getsigmask(pid: Pid) -> Result { + ptrace_get_data::(Request::PTRACE_GETSIGMASK, pid) +} + /// Get ptrace syscall info as with `ptrace(PTRACE_GET_SYSCALL_INFO,...)` /// Only available on Linux 5.3+ #[cfg(all(target_os = "linux", target_env = "gnu"))] @@ -404,6 +411,19 @@ pub fn setsiginfo(pid: Pid, sig: &siginfo_t) -> Result<()> { } } +/// Set sigmask as with `ptrace(PTRACE_SETSIGMASK,...)` +pub fn setsigmask(pid: Pid, mask: u64) -> Result<()> { + unsafe { + ptrace_other( + Request::PTRACE_SETSIGMASK, + pid, + mem::size_of::() as _, + &mask as *const _ as *mut c_void, + ) + .map(drop) + } +} + /// Sets the process as traceable, as with `ptrace(PTRACE_TRACEME, ...)` /// /// Indicates that this process is to be traced by its parent. diff --git a/test/sys/test_ptrace.rs b/test/sys/test_ptrace.rs index 42bf73c3a3..510135223c 100644 --- a/test/sys/test_ptrace.rs +++ b/test/sys/test_ptrace.rs @@ -66,6 +66,25 @@ fn test_ptrace_setsiginfo() { } } +// Just make sure ptrace_getsigmask can be called at all, for now. +#[test] +fn test_ptrace_getsigmask() { + require_capability!("test_ptrace_getsigmask", CAP_SYS_PTRACE); + if let Err(Errno::EOPNOTSUPP) = ptrace::getsigmask(getpid()) { + panic!("ptrace_getsigmask returns Errno::EOPNOTSUPP!"); + } +} + +// Just make sure ptrace_setsigmask can be called at all, for now. +#[test] +fn test_ptrace_setsigmask() { + require_capability!("test_ptrace_setsigmask", CAP_SYS_PTRACE); + let sigmask = unsafe { mem::zeroed() }; + if let Err(Errno::EOPNOTSUPP) = ptrace::setsigmask(getpid(), &sigmask) { + panic!("ptrace_setsigmask returns Errno::EOPNOTSUPP!"); + } +} + #[test] fn test_ptrace_cont() { use nix::sys::ptrace;