Skip to content

Commit

Permalink
allow signal injection in ptrace::syscall and ptrace::detach
Browse files Browse the repository at this point in the history
  • Loading branch information
frangio committed Jun 9, 2019
1 parent 83407c5 commit be06661
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 10 deletions.
13 changes: 10 additions & 3 deletions src/sys/ptrace/bsd.rs
Expand Up @@ -84,9 +84,16 @@ pub fn attach(pid: Pid) -> Result<()> {

/// Detaches the current running process, as with `ptrace(PT_DETACH, ...)`
///
/// Detaches from the process specified in pid allowing it to run freely
pub fn detach(pid: Pid) -> Result<()> {
unsafe { ptrace_other(Request::PT_DETACH, pid, ptr::null_mut(), 0).map(drop) }
/// Detaches from the process specified in pid allowing it to run freely, optionally delivering a
/// signal specified by `sig`.
pub fn detach<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
let data = match sig.into() {
Some(s) => s as c_int,
None => 0,
};
unsafe {
ptrace_other(Request::PT_DETACH, pid, ptr::null_mut(), data).map(drop)
}
}

/// Restart the stopped tracee process, as with `ptrace(PTRACE_CONT, ...)`
Expand Down
22 changes: 16 additions & 6 deletions src/sys/ptrace/linux.rs
Expand Up @@ -290,14 +290,19 @@ pub fn traceme() -> Result<()> {

/// Ask for next syscall, as with `ptrace(PTRACE_SYSCALL, ...)`
///
/// Arranges for the tracee to be stopped at the next entry to or exit from a system call.
pub fn syscall(pid: Pid) -> Result<()> {
/// Arranges for the tracee to be stopped at the next entry to or exit from a system call,
/// optionally delivering a signal specified by `sig`.
pub fn syscall<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
let data = match sig.into() {
Some(s) => s as i32 as *mut c_void,
None => ptr::null_mut(),
};
unsafe {
ptrace_other(
Request::PTRACE_SYSCALL,
pid,
ptr::null_mut(),
ptr::null_mut(),
data,
).map(drop) // ignore the useless return value
}
}
Expand All @@ -318,14 +323,19 @@ pub fn attach(pid: Pid) -> Result<()> {

/// Detaches the current running process, as with `ptrace(PTRACE_DETACH, ...)`
///
/// Detaches from the process specified in pid allowing it to run freely
pub fn detach(pid: Pid) -> Result<()> {
/// Detaches from the process specified in pid allowing it to run freely, optionally delivering a
/// signal specified by `sig`.
pub fn detach<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
let data = match sig.into() {
Some(s) => s as i32 as *mut c_void,
None => ptr::null_mut(),
};
unsafe {
ptrace_other(
Request::PTRACE_DETACH,
pid,
ptr::null_mut(),
ptr::null_mut()
data
).map(drop)
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/sys/test_wait.rs
Expand Up @@ -82,7 +82,7 @@ mod ptrace {
assert!(ptrace::setoptions(child, Options::PTRACE_O_TRACESYSGOOD | Options::PTRACE_O_TRACEEXIT).is_ok());

// First, stop on the next system call, which will be exit()
assert!(ptrace::syscall(child).is_ok());
assert!(ptrace::syscall(child, None).is_ok());
assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceSyscall(child)));
// Then get the ptrace event for the process exiting
assert!(ptrace::cont(child, None).is_ok());
Expand Down

0 comments on commit be06661

Please sign in to comment.