-
Notifications
You must be signed in to change notification settings - Fork 713
Description
I was trying to write some code using ptrace::syscall_info
and only received garbage / uninitialized data. The reason seems to be that the current implementation passes a null pointer for the addr
parameter instead of std::mem::size_of::<libc::ptrace_syscall_info>()
.
The code for ptrace::syscall_info(pid)
uses the function ptrace_get_data
:
#[cfg(all(target_os = "linux", target_env = "gnu"))]
pub fn syscall_info(pid: Pid) -> Result<libc::ptrace_syscall_info> {
ptrace_get_data::<libc::ptrace_syscall_info>(Request::PTRACE_GET_SYSCALL_INFO, pid)
}
This function will always pass a null pointer using ptr::null_mut::<T>()
for the third parameter (addr
).
fn ptrace_get_data<T>(request: Request, pid: Pid) -> Result<T> {
let mut data = mem::MaybeUninit::<T>::uninit();
let res = unsafe {
libc::ptrace(
request as RequestType, // op
libc::pid_t::from(pid), // pid
ptr::null_mut::<T>(), // addr
data.as_mut_ptr(), // data
)
};
Errno::result(res)?;
Ok(unsafe { data.assume_init() })
}
This seems to be incorrect. The documentation for PTRACE_GET_SYSCALL_INFO states:
The addr argument contains the size of the buffer pointed to by the data argument (i.e., sizeof(struct ptrace_syscall_info)). [...] If the size of the data to be written by the kernel exceeds the size specified by the addr argument, the output data is truncated.
Therefore I'm guessing that nothing gets written to the buffer if 0 is passed. It also does not seem to be an error condition, so the function still returns Ok(_)
. The following test code seems to fix the issue:
let mut data = std::mem::MaybeUninit::<libc::ptrace_syscall_info>::uninit();
let res = unsafe {
libc::ptrace(
Request::PTRACE_GET_SYSCALL_INFO as c_uint,
libc::pid_t::from(pid),
std::mem::size_of::<libc::ptrace_syscall_info>(),
data.as_mut_ptr())
};
Errno::result(res)?;
let info = unsafe { data.assume_init() };
Tested on kernel:
Linux dev-test 6.8.12-13-pve #1 SMP PREEMPT_DYNAMIC PMX 6.8.12-13 (2025-07-22T10:00Z) x86_64 GNU/Linux
(On Debian bookworm in a Proxmox LXC container)