Skip to content

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

Open
@Evian-Zhang

Description

@Evian-Zhang

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions