mirror of https://github.com/golang/go.git
syscall: use dup3 in forkAndExecInChild on OpenBSD
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>
This commit is contained in:
parent
bf97c99b62
commit
55a60cadc3
|
|
@ -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++
|
||||
|
|
|
|||
|
|
@ -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++
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
var dupTrampoline = abi.FuncPCABI0(libc_dup2_trampoline)
|
||||
|
||||
type SockaddrDatalink struct {
|
||||
Len uint8
|
||||
Family uint8
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import (
|
|||
"internal/abi"
|
||||
)
|
||||
|
||||
var dupTrampoline = abi.FuncPCABI0(libc_dup3_trampoline)
|
||||
|
||||
func init() {
|
||||
execveOpenBSD = execve
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue