aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/syscall
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2018-01-09 01:23:08 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-01-09 01:23:08 +0000
commit1a2f01efa63036a5104f203a4789e682c0e0915d (patch)
tree373e15778dc8295354584e1f86915ae493b604ff /libgo/go/syscall
parent8799df67f2dab88f9fda11739c501780a85575e2 (diff)
downloadgcc-1a2f01efa63036a5104f203a4789e682c0e0915d.zip
gcc-1a2f01efa63036a5104f203a4789e682c0e0915d.tar.gz
gcc-1a2f01efa63036a5104f203a4789e682c0e0915d.tar.bz2
libgo: update to Go1.10beta1
Update the Go library to the 1.10beta1 release. Requires a few changes to the compiler for modifications to the map runtime code, and to handle some nowritebarrier cases in the runtime. Reviewed-on: https://go-review.googlesource.com/86455 gotools/: * Makefile.am (go_cmd_vet_files): New variable. (go_cmd_buildid_files, go_cmd_test2json_files): New variables. (s-zdefaultcc): Change from constants to functions. (noinst_PROGRAMS): Add vet, buildid, and test2json. (cgo$(EXEEXT)): Link against $(LIBGOTOOL). (vet$(EXEEXT)): New target. (buildid$(EXEEXT)): New target. (test2json$(EXEEXT)): New target. (install-exec-local): Install all $(noinst_PROGRAMS). (uninstall-local): Uninstasll all $(noinst_PROGRAMS). (check-go-tool): Depend on $(noinst_PROGRAMS). Copy down objabi.go. (check-runtime): Depend on $(noinst_PROGRAMS). (check-cgo-test, check-carchive-test): Likewise. (check-vet): New target. (check): Depend on check-vet. Look at cmd_vet-testlog. (.PHONY): Add check-vet. * Makefile.in: Rebuild. From-SVN: r256365
Diffstat (limited to 'libgo/go/syscall')
-rw-r--r--libgo/go/syscall/creds_test.go183
-rw-r--r--libgo/go/syscall/exec_freebsd.go18
-rw-r--r--libgo/go/syscall/exec_linux.go18
-rw-r--r--libgo/go/syscall/exec_linux_test.go25
-rw-r--r--libgo/go/syscall/exec_windows.go7
-rw-r--r--libgo/go/syscall/libcall_posix.go3
-rw-r--r--libgo/go/syscall/socket.go21
-rw-r--r--libgo/go/syscall/syscall.go9
-rw-r--r--libgo/go/syscall/syscall_unix_test.go3
9 files changed, 169 insertions, 118 deletions
diff --git a/libgo/go/syscall/creds_test.go b/libgo/go/syscall/creds_test.go
index 7c6ab1d..524689a 100644
--- a/libgo/go/syscall/creds_test.go
+++ b/libgo/go/syscall/creds_test.go
@@ -19,101 +19,116 @@ import (
// sockets. The SO_PASSCRED socket option is enabled on the sending
// socket for this to work.
func TestSCMCredentials(t *testing.T) {
- fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0)
- if err != nil {
- t.Fatalf("Socketpair: %v", err)
+ socketTypeTests := []struct {
+ socketType int
+ dataLen int
+ }{
+ {
+ syscall.SOCK_STREAM,
+ 1,
+ }, {
+ syscall.SOCK_DGRAM,
+ 0,
+ },
}
- defer syscall.Close(fds[0])
- defer syscall.Close(fds[1])
- err = syscall.SetsockoptInt(fds[0], syscall.SOL_SOCKET, syscall.SO_PASSCRED, 1)
- if err != nil {
- t.Fatalf("SetsockoptInt: %v", err)
- }
+ for _, tt := range socketTypeTests {
+ fds, err := syscall.Socketpair(syscall.AF_LOCAL, tt.socketType, 0)
+ if err != nil {
+ t.Fatalf("Socketpair: %v", err)
+ }
+ defer syscall.Close(fds[0])
+ defer syscall.Close(fds[1])
- srvFile := os.NewFile(uintptr(fds[0]), "server")
- defer srvFile.Close()
- srv, err := net.FileConn(srvFile)
- if err != nil {
- t.Errorf("FileConn: %v", err)
- return
- }
- defer srv.Close()
+ err = syscall.SetsockoptInt(fds[0], syscall.SOL_SOCKET, syscall.SO_PASSCRED, 1)
+ if err != nil {
+ t.Fatalf("SetsockoptInt: %v", err)
+ }
- cliFile := os.NewFile(uintptr(fds[1]), "client")
- defer cliFile.Close()
- cli, err := net.FileConn(cliFile)
- if err != nil {
- t.Errorf("FileConn: %v", err)
- return
- }
- defer cli.Close()
+ srvFile := os.NewFile(uintptr(fds[0]), "server")
+ defer srvFile.Close()
+ srv, err := net.FileConn(srvFile)
+ if err != nil {
+ t.Errorf("FileConn: %v", err)
+ return
+ }
+ defer srv.Close()
+
+ cliFile := os.NewFile(uintptr(fds[1]), "client")
+ defer cliFile.Close()
+ cli, err := net.FileConn(cliFile)
+ if err != nil {
+ t.Errorf("FileConn: %v", err)
+ return
+ }
+ defer cli.Close()
+
+ var ucred syscall.Ucred
+ if os.Getuid() != 0 {
+ ucred.Pid = int32(os.Getpid())
+ ucred.Uid = 0
+ ucred.Gid = 0
+ oob := syscall.UnixCredentials(&ucred)
+ _, _, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
+ if op, ok := err.(*net.OpError); ok {
+ err = op.Err
+ }
+ if sys, ok := err.(*os.SyscallError); ok {
+ err = sys.Err
+ }
+ if err != syscall.EPERM {
+ t.Fatalf("WriteMsgUnix failed with %v, want EPERM", err)
+ }
+ }
- var ucred syscall.Ucred
- if os.Getuid() != 0 {
ucred.Pid = int32(os.Getpid())
- ucred.Uid = 0
- ucred.Gid = 0
+ ucred.Uid = uint32(os.Getuid())
+ ucred.Gid = uint32(os.Getgid())
oob := syscall.UnixCredentials(&ucred)
- _, _, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
- if op, ok := err.(*net.OpError); ok {
- err = op.Err
+
+ // On SOCK_STREAM, this is internally going to send a dummy byte
+ n, oobn, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
+ if err != nil {
+ t.Fatalf("WriteMsgUnix: %v", err)
}
- if sys, ok := err.(*os.SyscallError); ok {
- err = sys.Err
+ if n != 0 {
+ t.Fatalf("WriteMsgUnix n = %d, want 0", n)
}
- if err != syscall.EPERM {
- t.Fatalf("WriteMsgUnix failed with %v, want EPERM", err)
+ if oobn != len(oob) {
+ t.Fatalf("WriteMsgUnix oobn = %d, want %d", oobn, len(oob))
}
- }
-
- ucred.Pid = int32(os.Getpid())
- ucred.Uid = uint32(os.Getuid())
- ucred.Gid = uint32(os.Getgid())
- oob := syscall.UnixCredentials(&ucred)
-
- // this is going to send a dummy byte
- n, oobn, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
- if err != nil {
- t.Fatalf("WriteMsgUnix: %v", err)
- }
- if n != 0 {
- t.Fatalf("WriteMsgUnix n = %d, want 0", n)
- }
- if oobn != len(oob) {
- t.Fatalf("WriteMsgUnix oobn = %d, want %d", oobn, len(oob))
- }
- oob2 := make([]byte, 10*len(oob))
- n, oobn2, flags, _, err := srv.(*net.UnixConn).ReadMsgUnix(nil, oob2)
- if err != nil {
- t.Fatalf("ReadMsgUnix: %v", err)
- }
- if flags != 0 {
- t.Fatalf("ReadMsgUnix flags = 0x%x, want 0", flags)
- }
- if n != 1 {
- t.Fatalf("ReadMsgUnix n = %d, want 1 (dummy byte)", n)
- }
- if oobn2 != oobn {
- // without SO_PASSCRED set on the socket, ReadMsgUnix will
- // return zero oob bytes
- t.Fatalf("ReadMsgUnix oobn = %d, want %d", oobn2, oobn)
- }
- oob2 = oob2[:oobn2]
- if !bytes.Equal(oob, oob2) {
- t.Fatal("ReadMsgUnix oob bytes don't match")
- }
+ oob2 := make([]byte, 10*len(oob))
+ n, oobn2, flags, _, err := srv.(*net.UnixConn).ReadMsgUnix(nil, oob2)
+ if err != nil {
+ t.Fatalf("ReadMsgUnix: %v", err)
+ }
+ if flags != 0 {
+ t.Fatalf("ReadMsgUnix flags = 0x%x, want 0", flags)
+ }
+ if n != tt.dataLen {
+ t.Fatalf("ReadMsgUnix n = %d, want %d", n, tt.dataLen)
+ }
+ if oobn2 != oobn {
+ // without SO_PASSCRED set on the socket, ReadMsgUnix will
+ // return zero oob bytes
+ t.Fatalf("ReadMsgUnix oobn = %d, want %d", oobn2, oobn)
+ }
+ oob2 = oob2[:oobn2]
+ if !bytes.Equal(oob, oob2) {
+ t.Fatal("ReadMsgUnix oob bytes don't match")
+ }
- scm, err := syscall.ParseSocketControlMessage(oob2)
- if err != nil {
- t.Fatalf("ParseSocketControlMessage: %v", err)
- }
- newUcred, err := syscall.ParseUnixCredentials(&scm[0])
- if err != nil {
- t.Fatalf("ParseUnixCredentials: %v", err)
- }
- if *newUcred != ucred {
- t.Fatalf("ParseUnixCredentials = %+v, want %+v", newUcred, ucred)
+ scm, err := syscall.ParseSocketControlMessage(oob2)
+ if err != nil {
+ t.Fatalf("ParseSocketControlMessage: %v", err)
+ }
+ newUcred, err := syscall.ParseUnixCredentials(&scm[0])
+ if err != nil {
+ t.Fatalf("ParseUnixCredentials: %v", err)
+ }
+ if *newUcred != ucred {
+ t.Fatalf("ParseUnixCredentials = %+v, want %+v", newUcred, ucred)
+ }
}
}
diff --git a/libgo/go/syscall/exec_freebsd.go b/libgo/go/syscall/exec_freebsd.go
index 4ed32c0..1654b4b 100644
--- a/libgo/go/syscall/exec_freebsd.go
+++ b/libgo/go/syscall/exec_freebsd.go
@@ -5,21 +5,5 @@
package syscall
func forkExecPipe(p []int) error {
- err := Pipe2(p, O_CLOEXEC)
- if err == nil {
- return nil
- }
-
- // FreeBSD 9 fallback.
- // TODO: remove this for Go 1.10 per Issue 19072
- err = Pipe(p)
- if err != nil {
- return err
- }
- _, err = fcntl(p[0], F_SETFD, FD_CLOEXEC)
- if err != nil {
- return err
- }
- _, err = fcntl(p[1], F_SETFD, FD_CLOEXEC)
- return err
+ return Pipe2(p, O_CLOEXEC)
}
diff --git a/libgo/go/syscall/exec_linux.go b/libgo/go/syscall/exec_linux.go
index 6e2f83e..4cc018b 100644
--- a/libgo/go/syscall/exec_linux.go
+++ b/libgo/go/syscall/exec_linux.go
@@ -208,14 +208,6 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att
}
}
- // Enable tracing if requested.
- if sys.Ptrace {
- err1 = raw_ptrace(_PTRACE_TRACEME, 0, nil, nil)
- if err1 != 0 {
- goto childerror
- }
- }
-
// Session ID
if sys.Setsid {
err1 = raw_setsid()
@@ -406,6 +398,16 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att
}
}
+ // Enable tracing if requested.
+ // Do this right before exec so that we don't unnecessarily trace the runtime
+ // setting up after the fork. See issue #21428.
+ if sys.Ptrace {
+ err1 = raw_ptrace(_PTRACE_TRACEME, 0, nil, nil)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
// Time to exec.
err1 = raw_execve(argv0, &argv[0], &envv[0])
diff --git a/libgo/go/syscall/exec_linux_test.go b/libgo/go/syscall/exec_linux_test.go
index 114deec..17df8f4 100644
--- a/libgo/go/syscall/exec_linux_test.go
+++ b/libgo/go/syscall/exec_linux_test.go
@@ -23,6 +23,24 @@ import (
"unsafe"
)
+func isDocker() bool {
+ _, err := os.Stat("/.dockerenv")
+ return err == nil
+}
+
+func isLXC() bool {
+ return os.Getenv("container") == "lxc"
+}
+
+func skipInContainer(t *testing.T) {
+ if isDocker() {
+ t.Skip("skip this test in Docker container")
+ }
+ if isLXC() {
+ t.Skip("skip this test in LXC container")
+ }
+}
+
// Check if we are in a chroot by checking if the inode of / is
// different from 2 (there is no better test available to non-root on
// linux).
@@ -35,6 +53,7 @@ func isChrooted(t *testing.T) bool {
}
func checkUserNS(t *testing.T) {
+ skipInContainer(t)
if _, err := os.Stat("/proc/self/ns/user"); err != nil {
if os.IsNotExist(err) {
t.Skip("kernel doesn't support user namespaces")
@@ -114,7 +133,7 @@ func TestCloneNEWUSERAndRemapRootEnableSetgroups(t *testing.T) {
if os.Getuid() != 0 {
t.Skip("skipping root only test")
}
- testNEWUSERRemap(t, 0, 0, false)
+ testNEWUSERRemap(t, 0, 0, true)
}
func TestCloneNEWUSERAndRemapNoRootDisableSetgroups(t *testing.T) {
@@ -147,6 +166,7 @@ func TestEmptyCredGroupsDisableSetgroups(t *testing.T) {
}
func TestUnshare(t *testing.T) {
+ skipInContainer(t)
// Make sure we are running as root so we have permissions to use unshare
// and create a network namespace.
if os.Getuid() != 0 {
@@ -293,6 +313,7 @@ func TestUnshareMountNameSpaceHelper(*testing.T) {
// Test for Issue 38471: unshare fails because systemd has forced / to be shared
func TestUnshareMountNameSpace(t *testing.T) {
+ skipInContainer(t)
// Make sure we are running as root so we have permissions to use unshare
// and create a network namespace.
if os.Getuid() != 0 {
@@ -342,6 +363,7 @@ func TestUnshareMountNameSpace(t *testing.T) {
// Test for Issue 20103: unshare fails when chroot is used
func TestUnshareMountNameSpaceChroot(t *testing.T) {
+ skipInContainer(t)
// Make sure we are running as root so we have permissions to use unshare
// and create a network namespace.
if os.Getuid() != 0 {
@@ -477,6 +499,7 @@ func TestAmbientCapsHelper(*testing.T) {
}
func TestAmbientCaps(t *testing.T) {
+ skipInContainer(t)
// Make sure we are running as root so we have permissions to use unshare
// and create a network namespace.
if os.Getuid() != 0 {
diff --git a/libgo/go/syscall/exec_windows.go b/libgo/go/syscall/exec_windows.go
index cafce1e..91b0e84 100644
--- a/libgo/go/syscall/exec_windows.go
+++ b/libgo/go/syscall/exec_windows.go
@@ -222,6 +222,7 @@ type SysProcAttr struct {
HideWindow bool
CmdLine string // used if non-empty, else the windows command line is built by escaping the arguments passed to StartProcess
CreationFlags uint32
+ Token Token // if set, runs new process in the security context represented by the token
}
var zeroProcAttr ProcAttr
@@ -321,7 +322,11 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
pi := new(ProcessInformation)
flags := sys.CreationFlags | CREATE_UNICODE_ENVIRONMENT
- err = CreateProcess(argv0p, argvp, nil, nil, true, flags, createEnvBlock(attr.Env), dirp, si, pi)
+ if sys.Token != 0 {
+ err = CreateProcessAsUser(sys.Token, argv0p, argvp, nil, nil, true, flags, createEnvBlock(attr.Env), dirp, si, pi)
+ } else {
+ err = CreateProcess(argv0p, argvp, nil, nil, true, flags, createEnvBlock(attr.Env), dirp, si, pi)
+ }
if err != nil {
return 0, 0, err
}
diff --git a/libgo/go/syscall/libcall_posix.go b/libgo/go/syscall/libcall_posix.go
index 76941c8..01eb178 100644
--- a/libgo/go/syscall/libcall_posix.go
+++ b/libgo/go/syscall/libcall_posix.go
@@ -193,9 +193,6 @@ func FDZero(set *FdSet) {
//sysnb Dup2(oldfd int, newfd int) (err error)
//dup2(oldfd _C_int, newfd _C_int) _C_int
-//sys Exit(code int)
-//exit(code _C_int)
-
//sys Fchdir(fd int) (err error)
//fchdir(fd _C_int) _C_int
diff --git a/libgo/go/syscall/socket.go b/libgo/go/syscall/socket.go
index 93bbc38..d3ff636 100644
--- a/libgo/go/syscall/socket.go
+++ b/libgo/go/syscall/socket.go
@@ -79,7 +79,7 @@ type SockaddrUnix struct {
func (sa *SockaddrUnix) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
name := sa.Name
n := len(name)
- if n >= len(sa.raw.Path) {
+ if n > len(sa.raw.Path) {
return nil, 0, EINVAL
}
sa.raw.Family = AF_UNIX
@@ -93,6 +93,11 @@ func (sa *SockaddrUnix) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
sl += Socklen_t(n) + 1
}
sl = sa.raw.adjustAbstract(sl)
+ // Check again after adjustAbstract adjusts the length.
+ // This is testing whether the +1 for NUL puts us out of range.
+ if sl-2 > Socklen_t(len(sa.raw.Path)) {
+ return nil, 0, EINVAL
+ }
// length is family (uint16), name, NUL.
return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), sl, nil
@@ -343,8 +348,13 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
}
var dummy byte
if len(oob) > 0 {
+ var sockType int
+ sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
+ if err != nil {
+ return
+ }
// receive at least one normal byte
- if len(p) == 0 {
+ if sockType != SOCK_DGRAM && len(p) == 0 {
iov.Base = &dummy
iov.SetLen(1)
}
@@ -390,8 +400,13 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error)
}
var dummy byte
if len(oob) > 0 {
+ var sockType int
+ sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
+ if err != nil {
+ return 0, err
+ }
// send at least one normal byte
- if len(p) == 0 {
+ if sockType != SOCK_DGRAM && len(p) == 0 {
iov.Base = &dummy
iov.SetLen(1)
}
diff --git a/libgo/go/syscall/syscall.go b/libgo/go/syscall/syscall.go
index 8415383..8e785dd 100644
--- a/libgo/go/syscall/syscall.go
+++ b/libgo/go/syscall/syscall.go
@@ -86,22 +86,29 @@ var dummy *byte
const sizeofPtr uintptr = uintptr(unsafe.Sizeof(dummy))
+// Unix returns ts as the number of seconds and nanoseconds elapsed since the
+// Unix epoch.
func (ts *Timespec) Unix() (sec int64, nsec int64) {
return int64(ts.Sec), int64(ts.Nsec)
}
+// Unix returns tv as the number of seconds and nanoseconds elapsed since the
+// Unix epoch.
func (tv *Timeval) Unix() (sec int64, nsec int64) {
return int64(tv.Sec), int64(tv.Usec) * 1000
}
+// Nano returns ts as the number of nanoseconds elapsed since the Unix epoch.
func (ts *Timespec) Nano() int64 {
return int64(ts.Sec)*1e9 + int64(ts.Nsec)
}
+// Nano returns tv as the number of nanoseconds elapsed since the Unix epoch.
func (tv *Timeval) Nano() int64 {
return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
}
-// Getpagesize is provided by the runtime.
+// Getpagesize and Exit are provided by the runtime.
func Getpagesize() int
+func Exit(code int)
diff --git a/libgo/go/syscall/syscall_unix_test.go b/libgo/go/syscall/syscall_unix_test.go
index b1fe78d..637aece 100644
--- a/libgo/go/syscall/syscall_unix_test.go
+++ b/libgo/go/syscall/syscall_unix_test.go
@@ -180,6 +180,9 @@ func TestPassFD(t *testing.T) {
uc.Close()
})
_, oobn, _, _, err := uc.ReadMsgUnix(buf, oob)
+ if err != nil {
+ t.Fatalf("ReadMsgUnix: %v", err)
+ }
closeUnix.Stop()
scms, err := syscall.ParseSocketControlMessage(oob[:oobn])