libgo: fix ptrace syscall hooks into glibc
authorPaul E. Murphy <murp@ibm.com>
Tue, 15 Sep 2020 19:18:28 +0000 (14:18 -0500)
committerIan Lance Taylor <iant@golang.org>
Thu, 17 Sep 2020 19:14:09 +0000 (12:14 -0700)
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

gcc/go/gofrontend/MERGE
libgo/go/syscall/libcall_glibc.go
libgo/go/syscall/libcall_linux.go
libgo/runtime/go-varargs.c

index df9d2118dfd1e1a65498decd34a3f017c3ec35fc..6b590f6fd9465e9dbb3b63f6f32dad46d339d002 100644 (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.
index a90fc9b3f8bdd5278ee8248d585cdb865e642fa2..823343d5075a8aaa0f339f657145dade50614045 100644 (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
index 88286c07b6e10ded29412f7b1e5df945609aee20..78fda0ea7ef1c6c93a092928b84a71035e670342 100644 (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
index 2b186ef8b81963785e2bf63211847b25911b1603..f9270a97bfde1ce096ebae958bb9a12382dee70b 100644 (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