diff options
author | Ian Lance Taylor <iant@golang.org> | 2018-01-09 01:23:08 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-01-09 01:23:08 +0000 |
commit | 1a2f01efa63036a5104f203a4789e682c0e0915d (patch) | |
tree | 373e15778dc8295354584e1f86915ae493b604ff /libgo/go/syscall | |
parent | 8799df67f2dab88f9fda11739c501780a85575e2 (diff) | |
download | gcc-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.go | 183 | ||||
-rw-r--r-- | libgo/go/syscall/exec_freebsd.go | 18 | ||||
-rw-r--r-- | libgo/go/syscall/exec_linux.go | 18 | ||||
-rw-r--r-- | libgo/go/syscall/exec_linux_test.go | 25 | ||||
-rw-r--r-- | libgo/go/syscall/exec_windows.go | 7 | ||||
-rw-r--r-- | libgo/go/syscall/libcall_posix.go | 3 | ||||
-rw-r--r-- | libgo/go/syscall/socket.go | 21 | ||||
-rw-r--r-- | libgo/go/syscall/syscall.go | 9 | ||||
-rw-r--r-- | libgo/go/syscall/syscall_unix_test.go | 3 |
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]) |