nix icon indicating copy to clipboard operation
nix copied to clipboard

`ptrace::getregs` & `ptrace::getregset` may lead to UB of uninitialized data read

Open Evian-Zhang opened this issue 1 year ago • 4 comments
trafficstars

ptrace::getregs and ptrace::getregset are used to get register values of certain process (tracee), which utilizes the ptrace(PTRACE_GETREGSET, ..) syscall:

pub fn getregset<S: RegisterSet>(pid: Pid) -> Result<S::Regs> {
    let request = Request::PTRACE_GETREGSET;
    let mut data = mem::MaybeUninit::<S::Regs>::uninit();
    let mut iov = libc::iovec {
        iov_base: data.as_mut_ptr().cast(),
        iov_len: mem::size_of::<S::Regs>(),
    };
    unsafe {
        ptrace_other(
            request,
            pid,
            S::VALUE as i32 as AddressType,
            (&mut iov as *mut libc::iovec).cast(),
        )?;
    };
    Ok(unsafe { data.assume_init() })
}

In amd64 Linux, if the tracer is 64bit process, tracee is 32bit process, the S::Regs will be resolved to 64bit version of libc::user_regs_struct, while after the syscall return, the S::VALUE buffer is filled by kernel with 32bit version of such struct. (The iovec.iov_len field will be 68 after returning, which confirms such thing). Reading the returned S::Regs will lead to uninitialized data, which is UB.

Evian-Zhang avatar Jun 14 '24 07:06 Evian-Zhang