libgo: fix ptrace syscall hooks into glibc

ptrace is actually declared as a variadic function.  On ppc64le
the ABI requires to the caller to allocate space for the parameters
and allows the caller to modify them.

On ppc64le, depending on how and what version of GCC is used,
it will save to parameter save area.  This happened to clobber
a saved LR, and caused syscall.TestExecPtrace to fail with a timeout
when the tracee segfaults, and waits for the parent process to inspect.

Wrap this function to avoid directly calling glibc's ptrace from go.

Fixes golang/go#36698
Fixes go/92567

Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/254755
This commit is contained in:
Paul E. Murphy 2020-09-15 14:18:28 -05:00 committed by Ian Lance Taylor
parent 4839de55e2
commit c560591408
4 changed files with 19 additions and 3 deletions

View File

@ -1,4 +1,4 @@
a47485cd0e9ce6a8b3e88e53ccc0a440f0bd4351
6fd6418efb983827717f648a11bb5ca6fe93af30
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.

View File

@ -32,7 +32,7 @@ func Futimes(fd int, tv []Timeval) (err error) {
}
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
//ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long
//__go_ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long
//sys accept4(fd int, sa *RawSockaddrAny, len *Socklen_t, flags int) (nfd int, err error)
//accept4(fd _C_int, sa *RawSockaddrAny, len *Socklen_t, flags _C_int) _C_int

View File

@ -11,7 +11,7 @@ import (
)
//sysnb raw_ptrace(request int, pid int, addr *byte, data *byte) (err Errno)
//ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long
//__go_ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long
func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
// The peek requests are machine-size oriented, so we wrap it

View File

@ -18,6 +18,9 @@
#ifdef HAVE_SYS_SYSCALL_H
#include <sys/syscall.h>
#endif
#ifdef HAVE_SYS_PTRACE_H
#include <sys/ptrace.h>
#endif
/* The syscall package calls C functions. The Go compiler can not
represent a C varargs functions. On some systems it's important
@ -110,3 +113,16 @@ __go_syscall6(uintptr_t flag, uintptr_t a1, uintptr_t a2, uintptr_t a3,
}
#endif
#ifdef HAVE_SYS_PTRACE_H
// Despite documented appearances, this is actually implemented as
// a variadic function within glibc.
long
__go_ptrace(int request, pid_t pid, uintptr_t addr, uintptr_t data)
{
return ptrace (request, pid, addr, data);
}
#endif