]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: use rawSyscall6 to call ptrace in forkAndExecInChild
authorqmuntal <quimmuntal@gmail.com>
Thu, 2 Oct 2025 13:12:30 +0000 (15:12 +0200)
committerQuim Muntal <quimmuntal@gmail.com>
Tue, 21 Oct 2025 17:45:23 +0000 (10:45 -0700)
On darwin and openbsd, the autogenerated ptrace wrapper is
nosplit because it is called from forkAndExecInChild.

This makes it difficult to modify and improve the underlying
syscall mechanism, as ptrace is almost over the nosplit limit.

We better call ptrace directly using rawSyscall6 in
forkAndExecInChild so that we can lift the ptrace nosplit
restriction to.

Doing so also fixes a long-standing inconsistency:
forkAndExecInChild is documented to only allow rawSyscall, but
the ptrace wrapper is using non-raw syscalls.

Updates #64113

Change-Id: Ibbbb218511561c1a5cb5b6d288a691f9738b14a6
Reviewed-on: https://go-review.googlesource.com/c/go/+/708575
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/syscall/exec_libc2.go
src/syscall/mksyscall.pl
src/syscall/zsyscall_darwin_amd64.go
src/syscall/zsyscall_darwin_arm64.go
src/syscall/zsyscall_openbsd_386.go
src/syscall/zsyscall_openbsd_amd64.go
src/syscall/zsyscall_openbsd_arm.go
src/syscall/zsyscall_openbsd_arm64.go
src/syscall/zsyscall_openbsd_ppc64.go
src/syscall/zsyscall_openbsd_riscv64.go

index a0579627a300bf5f04432d47317963d829de1ccb..5de09dfe9980703aa50054c47d4a0d78b6cc50bf 100644 (file)
@@ -59,7 +59,6 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
                r1              uintptr
                nextfd          int
                i               int
-               err             error
                pgrp            _C_int
                cred            *Credential
                ngroups, groups uintptr
@@ -99,8 +98,12 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
 
        // Enable tracing if requested.
        if sys.Ptrace {
-               if err = ptrace(PTRACE_TRACEME, 0, 0, 0); err != nil {
-                       err1 = err.(Errno)
+               if runtime.GOOS == "ios" {
+                       err1 = ENOSYS
+                       goto childerror
+               }
+               _, _, err1 = rawSyscall6(abi.FuncPCABI0(libc_ptrace_trampoline), PTRACE_TRACEME, 0, 0, 0, 0, 0)
+               if err1 != 0 {
                        goto childerror
                }
        }
index b46a3f9438bd87842b066ed36c3cef6545d4d378..6be94c9c44f0657808baa18d5a92ae508815a429 100755 (executable)
@@ -141,12 +141,6 @@ while(<>) {
        # without reading the header.
        $text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
 
-       if ((($darwin || ($openbsd && $libc)) && $func =~ /^ptrace(Ptr)?$/)) {
-               # The ptrace function is called from forkAndExecInChild where stack
-               # growth is forbidden.
-               $text .= "//go:nosplit\n"
-       }
-
        # Go function header.
        my $out_decl = @out ? sprintf(" (%s)", join(', ', @out)) : "";
        $text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out_decl;
index 8812fb12cd19c6694a25f26f01dbcd5934cc51cb..fe4a264ed25c6632cc6f48c90c44a36a12017160 100644 (file)
@@ -2011,7 +2011,6 @@ func libc_fstatat64_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-//go:nosplit
 func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
        if runtime.GOOS == "ios" {
                panic("unimplemented")
index 22b096349d47b9fd3b2054c3311413308565acfd..8fd7392d5b50f2bf11b25ecbe551698d7300f547 100644 (file)
@@ -2011,7 +2011,6 @@ func libc_fstatat_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-//go:nosplit
 func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
        if runtime.GOOS == "ios" {
                panic("unimplemented")
index c8cf7f231b1cb55f726342663843d296d1b1bc15..d914e19da0d8d3095e14efbaedd9fcb39652c1f6 100644 (file)
@@ -1839,7 +1839,6 @@ func libc_exit_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-//go:nosplit
 func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
        _, _, e1 := syscall6(abi.FuncPCABI0(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
        if e1 != 0 {
index 9188756a870a0a9bb696f5665e876dfd282daac8..5efe4cd8686f223372ed1a514a7043d6633509b0 100644 (file)
@@ -1839,7 +1839,6 @@ func libc_exit_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-//go:nosplit
 func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
        _, _, e1 := syscall6(abi.FuncPCABI0(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
        if e1 != 0 {
index ecdfa636721893d5549a9fce42b1d808bfbcfc74..db8ea482ef59830d14bd29f3fad015e28e63b479 100644 (file)
@@ -1839,7 +1839,6 @@ func libc_exit_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-//go:nosplit
 func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
        _, _, e1 := syscall6(abi.FuncPCABI0(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
        if e1 != 0 {
index d28d3c5e1ea71eb1059e78b2726a1d1cfcccdc80..673791c8241471976a4daa9451e78759b053491b 100644 (file)
@@ -1839,7 +1839,6 @@ func libc_exit_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-//go:nosplit
 func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
        _, _, e1 := syscall6(abi.FuncPCABI0(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
        if e1 != 0 {
index 0e6828bcafdfebd0ea2c187058bdb3f816554e4d..7e0dc88a4c155f8eea596d0380d3d43874b0a856 100644 (file)
@@ -1839,7 +1839,6 @@ func libc_exit_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-//go:nosplit
 func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
        _, _, e1 := syscall6(abi.FuncPCABI0(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
        if e1 != 0 {
index 920147074d091b295520e7a8356cb601b31d6245..7b5a89ceac150d2a27426a8e71caa133a77f0dea 100644 (file)
@@ -1839,7 +1839,6 @@ func libc_exit_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-//go:nosplit
 func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
        _, _, e1 := syscall6(abi.FuncPCABI0(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
        if e1 != 0 {