Skip to content

Fix special ptraces #686

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions src/sys/ptrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,16 @@ fn ptrace_peek(request: ptrace::PtraceRequest, pid: Pid, addr: *mut c_void, data
}
}

/// Function for ptrace requests that return values from the data field.
/// Function for ptrace requests that return values from the data field.
/// Some ptrace get requests populate structs or larger elements than c_long
/// and therefore use the data field to return values. This function handles these
/// requests.
fn ptrace_get_data<T>(request: ptrace::PtraceRequest, pid: Pid) -> Result<T> {
// Creates an uninitialized pointer to store result in
let data: Box<T> = Box::new(unsafe { mem::uninitialized() });
let data: *mut c_void = unsafe { mem::transmute(data) };
ptrace(request, pid, ptr::null_mut(), data)?;
// Convert back into the original data format and return unboxed value
let data: Box<T> = unsafe { mem::transmute(data) };
Ok(*data)
// Creates an uninitialized pointer to store result in
let data: T = unsafe { mem::uninitialized() };
let res = unsafe { ffi::ptrace(request, pid.into(), ptr::null_mut(), &data as *const _ as *const c_void) };
Errno::result(res)?;
Ok(data)
}

fn ptrace_other(request: ptrace::PtraceRequest, pid: Pid, addr: *mut c_void, data: *mut c_void) -> Result<c_long> {
Expand All @@ -114,7 +112,8 @@ pub fn ptrace_setoptions(pid: Pid, options: ptrace::PtraceOptions) -> Result<()>
use self::ptrace::*;
use std::ptr;

ptrace(PTRACE_SETOPTIONS, pid, ptr::null_mut(), options as *mut c_void).map(drop)
let res = unsafe { ffi::ptrace(PTRACE_SETOPTIONS, pid.into(), ptr::null_mut(), options as *mut c_void) };
Errno::result(res).map(|_| ())
}

/// Gets a ptrace event as described by `ptrace(PTRACE_GETEVENTMSG,...)`
Expand Down
36 changes: 35 additions & 1 deletion test/sys/test_ptrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use nix::errno::*;
use nix::unistd::*;
use nix::sys::ptrace::*;
use nix::sys::ptrace::ptrace::*;
use std::ptr;

use std::{mem, ptr};

#[test]
fn test_ptrace() {
Expand All @@ -12,3 +13,36 @@ fn test_ptrace() {
let err = ptrace(PTRACE_ATTACH, getpid(), ptr::null_mut(), ptr::null_mut()).unwrap_err();
assert!(err == Error::Sys(Errno::EPERM) || err == Error::Sys(Errno::ENOSYS));
}

// Just make sure ptrace_setoptions can be called at all, for now.
#[test]
fn test_ptrace_setoptions() {
let err = ptrace_setoptions(getpid(), PTRACE_O_TRACESYSGOOD).unwrap_err();
assert!(err != Error::UnsupportedOperation);
}

// Just make sure ptrace_getevent can be called at all, for now.
#[test]
fn test_ptrace_getevent() {
let err = ptrace_getevent(getpid()).unwrap_err();
assert!(err != Error::UnsupportedOperation);
}

// Just make sure ptrace_getsiginfo can be called at all, for now.
#[test]
fn test_ptrace_getsiginfo() {
match ptrace_getsiginfo(getpid()) {
Err(Error::UnsupportedOperation) => panic!("ptrace_getsiginfo returns Error::UnsupportedOperation!"),
_ => (),
}
}

// Just make sure ptrace_setsiginfo can be called at all, for now.
#[test]
fn test_ptrace_setsiginfo() {
let siginfo = unsafe { mem::uninitialized() };
match ptrace_setsiginfo(getpid(), &siginfo) {
Err(Error::UnsupportedOperation) => panic!("ptrace_setsiginfo returns Error::UnsupportedOperation!"),
_ => (),
}
}