delve/pkg/proc/native/ptrace_linux_64bit.go
Alessandro Arzilli 95e33edf53
proc/native: fix syscalls to SYS_PROCESS_VM_READV (and WRITEV) (#3273)
Per https://pkg.go.dev/unsafe#Pointer conversions from unsafe.Pointer
to uintptr are only safe in limited circumstances. In particular only
conversions made in the syscall call are pinned.
Additionally add a call to runtime.KeepAlive to mitigate the bug
described in: https://github.com/golang/go/issues/58351
2023-02-14 09:32:13 -08:00

36 lines
1.1 KiB
Go

//go:build (linux && amd64) || (linux && arm64)
// +build linux,amd64 linux,arm64
package native
import (
"syscall"
"unsafe"
sys "golang.org/x/sys/unix"
)
// processVmRead calls process_vm_readv
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 := remoteIovec{base: addr, len: uintptr(len_iov)}
n, _, err := syscall.Syscall6(sys.SYS_PROCESS_VM_READV, uintptr(tid), uintptr(unsafe.Pointer(&local_iov)), 1, uintptr(unsafe.Pointer(&remote_iov)), 1, 0)
if err != syscall.Errno(0) {
return 0, err
}
return int(n), nil
}
// processVmWrite calls process_vm_writev
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 := remoteIovec{base: addr, len: uintptr(len_iov)}
n, _, err := syscall.Syscall6(sys.SYS_PROCESS_VM_WRITEV, uintptr(tid), uintptr(unsafe.Pointer(&local_iov)), 1, uintptr(unsafe.Pointer(&remote_iov)), 1, 0)
if err != syscall.Errno(0) {
return 0, err
}
return int(n), nil
}