]> Cypherpunks.ru repositories - gostls13.git/commitdiff
syscall: use dup3 in forkAndExecInChild on OpenBSD
authorTobias Klauser <tklauser@distanz.ch>
Fri, 4 Mar 2022 08:49:32 +0000 (09:49 +0100)
committerTobias Klauser <tobias.klauser@gmail.com>
Sat, 5 Mar 2022 08:36:13 +0000 (08:36 +0000)
Use dup3(oldfd, newfd, O_CLOEXEC) to atomically duplicate the file
descriptor and mark is as close-on-exec instead of dup2 & fcntl.

The dup3 system call first appeared in OpenBSD 5.7.

Change-Id: Ic06c2c7089dcdbd931ee24e5e8c316879d81474e
Reviewed-on: https://go-review.googlesource.com/c/go/+/389974
Trust: Tobias Klauser <tobias.klauser@gmail.com>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
14 files changed:
src/syscall/exec_bsd.go
src/syscall/exec_libc2.go
src/syscall/syscall_darwin.go
src/syscall/syscall_openbsd.go
src/syscall/syscall_openbsd_libc.go
src/syscall/syscall_openbsd_mips64.go
src/syscall/zsyscall_openbsd_386.go
src/syscall/zsyscall_openbsd_386.s
src/syscall/zsyscall_openbsd_amd64.go
src/syscall/zsyscall_openbsd_amd64.s
src/syscall/zsyscall_openbsd_arm.go
src/syscall/zsyscall_openbsd_arm.s
src/syscall/zsyscall_openbsd_arm64.go
src/syscall/zsyscall_openbsd_arm64.s

index 148f5a91aa00e842697195db71f284bc8d545868..530b48cb707df70ccd83411c308fc1c4a448116f 100644 (file)
@@ -181,18 +181,17 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
        // Pass 1: look for fd[i] < i and move those up above len(fd)
        // so that pass 2 won't stomp on an fd it needs later.
        if pipe < nextfd {
-               switch runtime.GOOS {
-               case "netbsd":
+               if runtime.GOOS == "netbsd" || (runtime.GOOS == "openbsd" && runtime.GOARCH == "mips64") {
                        _, _, err1 = RawSyscall(_SYS_DUP3, uintptr(pipe), uintptr(nextfd), O_CLOEXEC)
-                       if err1 != 0 {
-                               goto childerror
-                       }
-               default:
+               } else {
                        _, _, err1 = RawSyscall(SYS_DUP2, uintptr(pipe), uintptr(nextfd), 0)
                        if err1 != 0 {
                                goto childerror
                        }
-                       RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
+                       _, _, err1 = RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
+               }
+               if err1 != 0 {
+                       goto childerror
                }
                pipe = nextfd
                nextfd++
@@ -202,18 +201,17 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
                        if nextfd == pipe { // don't stomp on pipe
                                nextfd++
                        }
-                       switch runtime.GOOS {
-                       case "netbsd":
+                       if runtime.GOOS == "netbsd" || (runtime.GOOS == "openbsd" && runtime.GOARCH == "mips64") {
                                _, _, err1 = RawSyscall(_SYS_DUP3, uintptr(fd[i]), uintptr(nextfd), O_CLOEXEC)
-                               if err1 != 0 {
-                                       goto childerror
-                               }
-                       default:
+                       } else {
                                _, _, err1 = RawSyscall(SYS_DUP2, uintptr(fd[i]), uintptr(nextfd), 0)
                                if err1 != 0 {
                                        goto childerror
                                }
-                               RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
+                               _, _, err1 = RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
+                       }
+                       if err1 != 0 {
+                               goto childerror
                        }
                        fd[i] = nextfd
                        nextfd++
index b05f053bbf3fa75cac478f50955454f624f521de..91a39ba1b8f617fe462d87b9e591381ee2045bc4 100644 (file)
@@ -8,6 +8,7 @@ package syscall
 
 import (
        "internal/abi"
+       "runtime"
        "unsafe"
 )
 
@@ -180,11 +181,18 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
        // Pass 1: look for fd[i] < i and move those up above len(fd)
        // so that pass 2 won't stomp on an fd it needs later.
        if pipe < nextfd {
-               _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(pipe), uintptr(nextfd), 0)
+               if runtime.GOOS == "openbsd" {
+                       _, _, err1 = rawSyscall(dupTrampoline, uintptr(pipe), uintptr(nextfd), O_CLOEXEC)
+               } else {
+                       _, _, err1 = rawSyscall(dupTrampoline, uintptr(pipe), uintptr(nextfd), 0)
+                       if err1 != 0 {
+                               goto childerror
+                       }
+                       _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(nextfd), F_SETFD, FD_CLOEXEC)
+               }
                if err1 != 0 {
                        goto childerror
                }
-               rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(nextfd), F_SETFD, FD_CLOEXEC)
                pipe = nextfd
                nextfd++
        }
@@ -193,11 +201,18 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
                        if nextfd == pipe { // don't stomp on pipe
                                nextfd++
                        }
-                       _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(fd[i]), uintptr(nextfd), 0)
+                       if runtime.GOOS == "openbsd" {
+                               _, _, err1 = rawSyscall(dupTrampoline, uintptr(fd[i]), uintptr(nextfd), O_CLOEXEC)
+                       } else {
+                               _, _, err1 = rawSyscall(dupTrampoline, uintptr(fd[i]), uintptr(nextfd), 0)
+                               if err1 != 0 {
+                                       goto childerror
+                               }
+                               _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(nextfd), F_SETFD, FD_CLOEXEC)
+                       }
                        if err1 != 0 {
                                goto childerror
                        }
-                       rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(nextfd), F_SETFD, FD_CLOEXEC)
                        fd[i] = nextfd
                        nextfd++
                }
index 902d6e77e11cb2bbf0e9512704a43ed8e77532f6..87fb5c2f62d20468ad67f297e297845b5a490638 100644 (file)
@@ -17,6 +17,8 @@ import (
        "unsafe"
 )
 
+var dupTrampoline = abi.FuncPCABI0(libc_dup2_trampoline)
+
 type SockaddrDatalink struct {
        Len    uint8
        Family uint8
index fa939ec5c8849501ba5467bebb7baf209b30a13e..30a95316e85d9a9e184209437c129115d1dae7a0 100644 (file)
@@ -136,6 +136,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
 //sys  Close(fd int) (err error)
 //sys  Dup(fd int) (nfd int, err error)
 //sys  Dup2(from int, to int) (err error)
+//sys  dup3(from int, to int, flags int) (err error)
 //sys  Fchdir(fd int) (err error)
 //sys  Fchflags(fd int, flags int) (err error)
 //sys  Fchmod(fd int, mode uint32) (err error)
index 15b68fd0fcf51c780738f12ee73b00526f1c36ac..516d02975c530a3ea1aea3b826039f7891797c80 100644 (file)
@@ -10,6 +10,8 @@ import (
        "internal/abi"
 )
 
+var dupTrampoline = abi.FuncPCABI0(libc_dup3_trampoline)
+
 func init() {
        execveOpenBSD = execve
 }
index e8ae2e9911bafa336ce75b93eeff422602366088..4508ad99b492a576397cfddf0582227d24d02f49 100644 (file)
@@ -4,7 +4,7 @@
 
 package syscall
 
-const _SYS_DUP3 = 0
+const _SYS_DUP3 = SYS_DUP3
 
 func setTimespec(sec, nsec int64) Timespec {
        return Timespec{Sec: sec, Nsec: nsec}
index 5f95d7a9c6dbcec0bb9faaa38e7230cf972624c5..2dcc4b2739dd4b9a303bbbdd2bb563bd0ee12cc5 100644 (file)
@@ -551,6 +551,20 @@ func libc_dup2_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func dup3(from int, to int, flags int) (err error) {
+       _, _, e1 := syscall(abi.FuncPCABI0(libc_dup3_trampoline), uintptr(from), uintptr(to), uintptr(flags))
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+func libc_dup3_trampoline()
+
+//go:cgo_import_dynamic libc_dup3 dup3 "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchdir(fd int) (err error) {
        _, _, e1 := syscall(abi.FuncPCABI0(libc_fchdir_trampoline), uintptr(fd), 0, 0)
        if e1 != 0 {
index d47a4f480d914afdd363be703dddd97a768681b9..e2c58625bb3b1ce845871a0ad8d9b24bfa983bf1 100644 (file)
@@ -69,6 +69,8 @@ TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0
        JMP     libc_dup(SB)
 TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0
        JMP     libc_dup2(SB)
+TEXT ·libc_dup3_trampoline(SB),NOSPLIT,$0-0
+       JMP     libc_dup3(SB)
 TEXT ·libc_fchdir_trampoline(SB),NOSPLIT,$0-0
        JMP     libc_fchdir(SB)
 TEXT ·libc_fchflags_trampoline(SB),NOSPLIT,$0-0
index 189bf887e6223fd29f665da34b292968f7513994..8d4cb9c1e1ce1165ecf0cf5b7164fed0e7725be7 100644 (file)
@@ -551,6 +551,20 @@ func libc_dup2_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func dup3(from int, to int, flags int) (err error) {
+       _, _, e1 := syscall(abi.FuncPCABI0(libc_dup3_trampoline), uintptr(from), uintptr(to), uintptr(flags))
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+func libc_dup3_trampoline()
+
+//go:cgo_import_dynamic libc_dup3 dup3 "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchdir(fd int) (err error) {
        _, _, e1 := syscall(abi.FuncPCABI0(libc_fchdir_trampoline), uintptr(fd), 0, 0)
        if e1 != 0 {
index e5c5dde930bb6062e4960c66bcc88aab91578d11..964c9ed9e1236d853a01a0449d88be5ae0e89e7a 100644 (file)
@@ -69,6 +69,8 @@ TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0
        JMP     libc_dup(SB)
 TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0
        JMP     libc_dup2(SB)
+TEXT ·libc_dup3_trampoline(SB),NOSPLIT,$0-0
+       JMP     libc_dup3(SB)
 TEXT ·libc_fchdir_trampoline(SB),NOSPLIT,$0-0
        JMP     libc_fchdir(SB)
 TEXT ·libc_fchflags_trampoline(SB),NOSPLIT,$0-0
index c7513a3ac9af4c754ea2c0f02b5177c499d76d23..d45bc02fbd3ec7d3fa4f077d33b5ceab5e30b8b7 100644 (file)
@@ -551,6 +551,20 @@ func libc_dup2_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func dup3(from int, to int, flags int) (err error) {
+       _, _, e1 := syscall(abi.FuncPCABI0(libc_dup3_trampoline), uintptr(from), uintptr(to), uintptr(flags))
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+func libc_dup3_trampoline()
+
+//go:cgo_import_dynamic libc_dup3 dup3 "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchdir(fd int) (err error) {
        _, _, e1 := syscall(abi.FuncPCABI0(libc_fchdir_trampoline), uintptr(fd), 0, 0)
        if e1 != 0 {
index d33f3aa3e05cf01f2e9220a78a1b6d92a5eb5037..5975780edb272b93dd97de690ab79aaeea27ca6b 100644 (file)
@@ -69,6 +69,8 @@ TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0
        JMP     libc_dup(SB)
 TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0
        JMP     libc_dup2(SB)
+TEXT ·libc_dup3_trampoline(SB),NOSPLIT,$0-0
+       JMP     libc_dup3(SB)
 TEXT ·libc_fchdir_trampoline(SB),NOSPLIT,$0-0
        JMP     libc_fchdir(SB)
 TEXT ·libc_fchflags_trampoline(SB),NOSPLIT,$0-0
index 293b70360021896c2d9a17a50af2367674d6ed42..e060b092fe316fb84337accbcd638725554863a0 100644 (file)
@@ -551,6 +551,20 @@ func libc_dup2_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func dup3(from int, to int, flags int) (err error) {
+       _, _, e1 := syscall(abi.FuncPCABI0(libc_dup3_trampoline), uintptr(from), uintptr(to), uintptr(flags))
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+func libc_dup3_trampoline()
+
+//go:cgo_import_dynamic libc_dup3 dup3 "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchdir(fd int) (err error) {
        _, _, e1 := syscall(abi.FuncPCABI0(libc_fchdir_trampoline), uintptr(fd), 0, 0)
        if e1 != 0 {
index 37778b1db5417be5fc6cd34f5d6037dec6da0bd1..2c4a0b0faf57d3a0434aa2006059eb895d933d89 100644 (file)
@@ -69,6 +69,8 @@ TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0
        JMP     libc_dup(SB)
 TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0
        JMP     libc_dup2(SB)
+TEXT ·libc_dup3_trampoline(SB),NOSPLIT,$0-0
+       JMP     libc_dup3(SB)
 TEXT ·libc_fchdir_trampoline(SB),NOSPLIT,$0-0
        JMP     libc_fchdir(SB)
 TEXT ·libc_fchflags_trampoline(SB),NOSPLIT,$0-0