proc/native/linux: replace uses of unix.Iovec for target addresses (#2922)

Replaces sys.Iovec with a similar struct that uses uintptr instead of
*byte for the base field when referring to addresses of the target
process, so that we do not generate invalid pointers.

Fixes #2919
This commit is contained in:
Alessandro Arzilli 2022-03-15 22:33:12 +01:00 committed by GitHub
parent 1d7bcd1d9e
commit a19931c9d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 12 additions and 4 deletions

@ -33,3 +33,11 @@ func ptraceSingleStep(pid, sig int) error {
}
return nil
}
// remoteIovec is like golang.org/x/sys/unix.Iovec but uses uintptr for the
// base field instead of *byte so that we can use it with addresses that
// belong to the target process.
type remoteIovec struct {
base uintptr
len uintptr
}

@ -69,7 +69,7 @@ func ptraceGetTls(gs int32, tid int) (uint32, error) {
func processVmRead(tid int, addr uintptr, data []byte) (int, error) {
len_iov := uint32(len(data))
local_iov := sys.Iovec{Base: &data[0], Len: len_iov}
remote_iov := sys.Iovec{Base: (*byte)(unsafe.Pointer(addr)), Len: len_iov}
remote_iov := remoteIovec{base: addr, len: uintptr(len_iov)}
p_local := uintptr(unsafe.Pointer(&local_iov))
p_remote := uintptr(unsafe.Pointer(&remote_iov))
n, _, err := syscall.Syscall6(sys.SYS_PROCESS_VM_READV, uintptr(tid), p_local, 1, p_remote, 1, 0)
@ -83,7 +83,7 @@ func processVmRead(tid int, addr uintptr, data []byte) (int, error) {
func processVmWrite(tid int, addr uintptr, data []byte) (int, error) {
len_iov := uint32(len(data))
local_iov := sys.Iovec{Base: &data[0], Len: len_iov}
remote_iov := sys.Iovec{Base: (*byte)(unsafe.Pointer(addr)), Len: len_iov}
remote_iov := remoteIovec{base: addr, len: uintptr(len_iov)}
p_local := uintptr(unsafe.Pointer(&local_iov))
p_remote := uintptr(unsafe.Pointer(&remote_iov))
n, _, err := syscall.Syscall6(sys.SYS_PROCESS_VM_WRITEV, uintptr(tid), p_local, 1, p_remote, 1, 0)

@ -14,7 +14,7 @@ import (
func processVmRead(tid int, addr uintptr, data []byte) (int, error) {
len_iov := uint64(len(data))
local_iov := sys.Iovec{Base: &data[0], Len: len_iov}
remote_iov := sys.Iovec{Base: (*byte)(unsafe.Pointer(addr)), Len: len_iov}
remote_iov := remoteIovec{base: addr, len: uintptr(len_iov)}
p_local := uintptr(unsafe.Pointer(&local_iov))
p_remote := uintptr(unsafe.Pointer(&remote_iov))
n, _, err := syscall.Syscall6(sys.SYS_PROCESS_VM_READV, uintptr(tid), p_local, 1, p_remote, 1, 0)
@ -28,7 +28,7 @@ func processVmRead(tid int, addr uintptr, data []byte) (int, error) {
func processVmWrite(tid int, addr uintptr, data []byte) (int, error) {
len_iov := uint64(len(data))
local_iov := sys.Iovec{Base: &data[0], Len: len_iov}
remote_iov := sys.Iovec{Base: (*byte)(unsafe.Pointer(addr)), Len: len_iov}
remote_iov := remoteIovec{base: addr, len: uintptr(len_iov)}
p_local := uintptr(unsafe.Pointer(&local_iov))
p_remote := uintptr(unsafe.Pointer(&remote_iov))
n, _, err := syscall.Syscall6(sys.SYS_PROCESS_VM_WRITEV, uintptr(tid), p_local, 1, p_remote, 1, 0)