diff options
Diffstat (limited to 'libgo/go/syscall')
-rw-r--r-- | libgo/go/syscall/errors_plan9.go | 10 | ||||
-rw-r--r-- | libgo/go/syscall/exec_bsd.go | 1 | ||||
-rw-r--r-- | libgo/go/syscall/exec_linux.go | 5 | ||||
-rw-r--r-- | libgo/go/syscall/exec_linux_test.go | 65 | ||||
-rw-r--r-- | libgo/go/syscall/exec_unix.go | 6 | ||||
-rw-r--r-- | libgo/go/syscall/libcall_bsd.go | 9 | ||||
-rw-r--r-- | libgo/go/syscall/libcall_linux.go | 9 | ||||
-rw-r--r-- | libgo/go/syscall/msan.go | 22 | ||||
-rw-r--r-- | libgo/go/syscall/msan0.go | 19 | ||||
-rw-r--r-- | libgo/go/syscall/race0.go | 25 | ||||
-rw-r--r-- | libgo/go/syscall/route_bsd.go | 11 | ||||
-rw-r--r-- | libgo/go/syscall/route_bsd_test.go | 35 | ||||
-rw-r--r-- | libgo/go/syscall/sockcmsg_unix.go | 6 | ||||
-rw-r--r-- | libgo/go/syscall/syscall.go | 3 | ||||
-rw-r--r-- | libgo/go/syscall/syscall_linux_mips64x.go | 20 | ||||
-rw-r--r-- | libgo/go/syscall/syscall_linux_test.go | 6 | ||||
-rw-r--r-- | libgo/go/syscall/syscall_unix.go | 21 |
17 files changed, 191 insertions, 82 deletions
diff --git a/libgo/go/syscall/errors_plan9.go b/libgo/go/syscall/errors_plan9.go index ede3d6a..d7634c9 100644 --- a/libgo/go/syscall/errors_plan9.go +++ b/libgo/go/syscall/errors_plan9.go @@ -46,3 +46,13 @@ var ( EACCES = NewError("access permission denied") EAFNOSUPPORT = NewError("address family not supported by protocol") ) + +// Notes +const ( + SIGABRT = Note("abort") + SIGALRM = Note("alarm") + SIGHUP = Note("hangup") + SIGINT = Note("interrupt") + SIGKILL = Note("kill") + SIGTERM = Note("interrupt") +) diff --git a/libgo/go/syscall/exec_bsd.go b/libgo/go/syscall/exec_bsd.go index 9042ce2..7512673 100644 --- a/libgo/go/syscall/exec_bsd.go +++ b/libgo/go/syscall/exec_bsd.go @@ -36,6 +36,7 @@ func runtime_AfterFork() // For the same reason compiler does not race instrument it. // The calls to RawSyscall are okay because they are assembly // functions that do not grow the stack. +//go:norace func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) { // Declare all variables at top in case any // declarations require heap allocation (e.g., err1). diff --git a/libgo/go/syscall/exec_linux.go b/libgo/go/syscall/exec_linux.go index 540efb3..6987bc1 100644 --- a/libgo/go/syscall/exec_linux.go +++ b/libgo/go/syscall/exec_linux.go @@ -57,6 +57,7 @@ func runtime_AfterFork() // For the same reason compiler does not race instrument it. // The calls to RawSyscall are okay because they are assembly // functions that do not grow the stack. +//go:norace func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) { // Declare all variables at top in case any // declarations require heap allocation (e.g., err1). @@ -201,11 +202,11 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr goto childerror } } - err1 = raw_setgid(int(cred.Gid)) + _, _, err1 = RawSyscall(SYS_SETGID, uintptr(cred.Gid), 0, 0) if err1 != 0 { goto childerror } - err1 = raw_setuid(int(cred.Uid)) + _, _, err1 = RawSyscall(SYS_SETUID, uintptr(cred.Uid), 0, 0) if err1 != 0 { goto childerror } diff --git a/libgo/go/syscall/exec_linux_test.go b/libgo/go/syscall/exec_linux_test.go index 60d2734..6d31941 100644 --- a/libgo/go/syscall/exec_linux_test.go +++ b/libgo/go/syscall/exec_linux_test.go @@ -10,13 +10,22 @@ import ( "io/ioutil" "os" "os/exec" - "regexp" - "strconv" "strings" "syscall" "testing" ) +// 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). +func isChrooted(t *testing.T) bool { + root, err := os.Stat("/") + if err != nil { + t.Fatalf("cannot stat /: %v", err) + } + return root.Sys().(*syscall.Stat_t).Ino != 2 +} + func whoamiCmd(t *testing.T, uid, gid int, setgroups bool) *exec.Cmd { if _, err := os.Stat("/proc/self/ns/user"); err != nil { if os.IsNotExist(err) { @@ -24,6 +33,26 @@ func whoamiCmd(t *testing.T, uid, gid int, setgroups bool) *exec.Cmd { } t.Fatalf("Failed to stat /proc/self/ns/user: %v", err) } + if isChrooted(t) { + // create_user_ns in the kernel (see + // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/kernel/user_namespace.c) + // forbids the creation of user namespaces when chrooted. + t.Skip("cannot create user namespaces when chrooted") + } + // On some systems, there is a sysctl setting. + if os.Getuid() != 0 { + data, errRead := ioutil.ReadFile("/proc/sys/kernel/unprivileged_userns_clone") + if errRead == nil && data[0] == '0' { + t.Skip("kernel prohibits user namespace in unprivileged process") + } + } + // When running under the Go continuous build, skip tests for + // now when under Kubernetes. (where things are root but not quite) + // Both of these are our own environment variables. + // See Issue 12815. + if os.Getenv("GO_BUILDER_NAME") != "" && os.Getenv("IN_KUBERNETES") == "1" { + t.Skip("skipping test on Kubernetes-based builders; see Issue 12815") + } cmd := exec.Command("whoami") cmd.SysProcAttr = &syscall.SysProcAttr{ Cloneflags: syscall.CLONE_NEWUSER, @@ -42,14 +71,6 @@ func testNEWUSERRemap(t *testing.T, uid, gid int, setgroups bool) { cmd := whoamiCmd(t, uid, gid, setgroups) out, err := cmd.CombinedOutput() if err != nil { - // On some systems, there is a sysctl setting. - if os.IsPermission(err) && os.Getuid() != 0 { - data, errRead := ioutil.ReadFile("/proc/sys/kernel/unprivileged_userns_clone") - if errRead == nil && data[0] == '0' { - t.Skip("kernel prohibits user namespace in unprivileged process") - } - } - t.Fatalf("Cmd failed with err %v, output: %s", err, out) } sout := strings.TrimSpace(string(out)) @@ -73,22 +94,6 @@ func TestCloneNEWUSERAndRemapRootEnableSetgroups(t *testing.T) { testNEWUSERRemap(t, 0, 0, false) } -// kernelVersion returns the major and minor versions of the Linux -// kernel version. It calls t.Skip if it can't figure it out. -func kernelVersion(t *testing.T) (int, int) { - bytes, err := ioutil.ReadFile("/proc/version") - if err != nil { - t.Skipf("can't get kernel version: %v", err) - } - matches := regexp.MustCompile("([0-9]+).([0-9]+)").FindSubmatch(bytes) - if len(matches) < 3 { - t.Skipf("can't get kernel version from %s", bytes) - } - major, _ := strconv.Atoi(string(matches[1])) - minor, _ := strconv.Atoi(string(matches[2])) - return major, minor -} - func TestCloneNEWUSERAndRemapNoRootDisableSetgroups(t *testing.T) { if os.Getuid() == 0 { t.Skip("skipping unprivileged user only test") @@ -109,3 +114,11 @@ func TestCloneNEWUSERAndRemapNoRootSetgroupsEnableSetgroups(t *testing.T) { t.Fatalf("Unprivileged gid_map rewriting with GidMappingsEnableSetgroups must fail") } } + +func TestEmptyCredGroupsDisableSetgroups(t *testing.T) { + cmd := whoamiCmd(t, os.Getuid(), os.Getgid(), false) + cmd.SysProcAttr.Credential = &syscall.Credential{} + if err := cmd.Run(); err != nil { + t.Fatal(err) + } +} diff --git a/libgo/go/syscall/exec_unix.go b/libgo/go/syscall/exec_unix.go index d1927de..3b772e6 100644 --- a/libgo/go/syscall/exec_unix.go +++ b/libgo/go/syscall/exec_unix.go @@ -65,12 +65,6 @@ import ( //sysnb raw_setgroups(size int, list unsafe.Pointer) (err Errno) //setgroups(size Size_t, list *Gid_t) _C_int -//sysnb raw_setuid(uid int) (err Errno) -//setuid(uid Uid_t) _C_int - -//sysnb raw_setgid(gid int) (err Errno) -//setgid(gid Gid_t) _C_int - // Lock synchronizing creation of new file descriptors with fork. // // We want the child in a fork/exec sequence to inherit only the diff --git a/libgo/go/syscall/libcall_bsd.go b/libgo/go/syscall/libcall_bsd.go index f772608..fe6a3e3 100644 --- a/libgo/go/syscall/libcall_bsd.go +++ b/libgo/go/syscall/libcall_bsd.go @@ -6,13 +6,16 @@ package syscall -import "unsafe" +import ( + "internal/race" + "unsafe" +) //sys sendfile(outfd int, infd int, offset *Offset_t, count int) (written int, err error) //sendfile(outfd _C_int, infd _C_int, offset *Offset_t, count Size_t) Ssize_t func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { - if raceenabled { - raceReleaseMerge(unsafe.Pointer(&ioSync)) + if race.Enabled { + race.ReleaseMerge(unsafe.Pointer(&ioSync)) } var soff Offset_t var psoff *Offset_t diff --git a/libgo/go/syscall/libcall_linux.go b/libgo/go/syscall/libcall_linux.go index f0479eb..ff81f54 100644 --- a/libgo/go/syscall/libcall_linux.go +++ b/libgo/go/syscall/libcall_linux.go @@ -6,7 +6,10 @@ package syscall -import "unsafe" +import ( + "internal/race" + "unsafe" +) //sys Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) //__go_openat(dirfd _C_int, path *byte, flags _C_int, mode Mode_t) _C_int @@ -321,8 +324,8 @@ func Pipe2(p []int, flags int) (err error) { //sys sendfile(outfd int, infd int, offset *Offset_t, count int) (written int, err error) //sendfile64(outfd _C_int, infd _C_int, offset *Offset_t, count Size_t) Ssize_t func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { - if raceenabled { - raceReleaseMerge(unsafe.Pointer(&ioSync)) + if race.Enabled { + race.ReleaseMerge(unsafe.Pointer(&ioSync)) } var soff Offset_t var psoff *Offset_t diff --git a/libgo/go/syscall/msan.go b/libgo/go/syscall/msan.go new file mode 100644 index 0000000..edd8d1e --- /dev/null +++ b/libgo/go/syscall/msan.go @@ -0,0 +1,22 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build msan + +package syscall + +import ( + "runtime" + "unsafe" +) + +const msanenabled = true + +func msanRead(addr unsafe.Pointer, len int) { + runtime.MSanRead(addr, len) +} + +func msanWrite(addr unsafe.Pointer, len int) { + runtime.MSanWrite(addr, len) +} diff --git a/libgo/go/syscall/msan0.go b/libgo/go/syscall/msan0.go new file mode 100644 index 0000000..7617494 --- /dev/null +++ b/libgo/go/syscall/msan0.go @@ -0,0 +1,19 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !msan + +package syscall + +import ( + "unsafe" +) + +const msanenabled = false + +func msanRead(addr unsafe.Pointer, len int) { +} + +func msanWrite(addr unsafe.Pointer, len int) { +} diff --git a/libgo/go/syscall/race0.go b/libgo/go/syscall/race0.go deleted file mode 100644 index b02f882..0000000 --- a/libgo/go/syscall/race0.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !race - -package syscall - -import ( - "unsafe" -) - -const raceenabled = false - -func raceAcquire(addr unsafe.Pointer) { -} - -func raceReleaseMerge(addr unsafe.Pointer) { -} - -func raceReadRange(addr unsafe.Pointer, len int) { -} - -func raceWriteRange(addr unsafe.Pointer, len int) { -} diff --git a/libgo/go/syscall/route_bsd.go b/libgo/go/syscall/route_bsd.go index c62fdc3..c635a13 100644 --- a/libgo/go/syscall/route_bsd.go +++ b/libgo/go/syscall/route_bsd.go @@ -44,6 +44,9 @@ func rsaAlignOf(salen int) int { // parseSockaddrLink parses b as a datalink socket address. func parseSockaddrLink(b []byte) (*SockaddrDatalink, error) { + if len(b) < 8 { + return nil, EINVAL + } sa, _, err := parseLinkLayerAddr(b[4:]) if err != nil { return nil, err @@ -77,16 +80,16 @@ func parseLinkLayerAddr(b []byte) (*SockaddrDatalink, int, error) { Slen byte } lla := (*linkLayerAddr)(unsafe.Pointer(&b[0])) - l := rsaAlignOf(int(4 + lla.Nlen + lla.Alen + lla.Slen)) + l := 4 + int(lla.Nlen) + int(lla.Alen) + int(lla.Slen) if len(b) < l { return nil, 0, EINVAL } b = b[4:] sa := &SockaddrDatalink{Type: lla.Type, Nlen: lla.Nlen, Alen: lla.Alen, Slen: lla.Slen} - for i := 0; len(sa.Data) > i && i < int(lla.Nlen+lla.Alen+lla.Slen); i++ { + for i := 0; len(sa.Data) > i && i < l-4; i++ { sa.Data[i] = int8(b[i]) } - return sa, l, nil + return sa, rsaAlignOf(l), nil } // parseSockaddrInet parses b as an internet socket address. @@ -336,7 +339,7 @@ func ParseRoutingMessage(b []byte) (msgs []RoutingMessage, err error) { return msgs, nil } -// ParseRoutingMessage parses msg's payload as raw sockaddrs and +// ParseRoutingSockaddr parses msg's payload as raw sockaddrs and // returns the slice containing the Sockaddr interfaces. func ParseRoutingSockaddr(msg RoutingMessage) ([]Sockaddr, error) { sas, err := msg.sockaddr() diff --git a/libgo/go/syscall/route_bsd_test.go b/libgo/go/syscall/route_bsd_test.go index 8617663..74d11f9 100644 --- a/libgo/go/syscall/route_bsd_test.go +++ b/libgo/go/syscall/route_bsd_test.go @@ -119,6 +119,41 @@ func TestRouteMonitor(t *testing.T) { <-tmo } +var parseInterfaceMessageTests = []*syscall.InterfaceMessage{ + // with link-layer address + { + Header: syscall.IfMsghdr{Version: syscall.RTM_VERSION, Addrs: syscall.RTA_IFP}, + Data: []uint8{ + 0x11, 0x12, 0x2, 0x0, 0x6, 0x3, 0x6, 0x0, + 0x77, 0x6d, 0x31, 0x01, 0x23, 0x45, 0xab, 0xcd, + 0xef, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + }, + }, + // without link-layer address + { + Header: syscall.IfMsghdr{Version: syscall.RTM_VERSION, Addrs: syscall.RTA_IFP}, + Data: []uint8{ + 0xe, 0x12, 0x4, 0x0, 0xf5, 0x6, 0x0, 0x0, + 0x70, 0x66, 0x6c, 0x6f, 0x67, 0x30, 0x0, 0x0, + }, + }, + // no data + { + Header: syscall.IfMsghdr{Version: syscall.RTM_VERSION, Addrs: syscall.RTA_IFP}, + Data: []uint8{ + 0x8, 0xa, 0xb, 0xc, 0xd, 0x0, 0x0, 0x0, + }, + }, +} + +func TestParseInterfaceMessage(t *testing.T) { + for i, tt := range parseInterfaceMessageTests { + if _, err := syscall.ParseRoutingSockaddr(tt); err != nil { + t.Errorf("#%d: %v", i, err) + } + } +} + type addrFamily byte func (f addrFamily) String() string { diff --git a/libgo/go/syscall/sockcmsg_unix.go b/libgo/go/syscall/sockcmsg_unix.go index 34c707d..bf32c98 100644 --- a/libgo/go/syscall/sockcmsg_unix.go +++ b/libgo/go/syscall/sockcmsg_unix.go @@ -85,10 +85,10 @@ func UnixRights(fds ...int) []byte { h.Level = SOL_SOCKET h.Type = SCM_RIGHTS h.SetLen(CmsgLen(datalen)) - data := uintptr(cmsgData(h)) + data := cmsgData(h) for _, fd := range fds { - *(*int32)(unsafe.Pointer(data)) = int32(fd) - data += 4 + *(*int32)(data) = int32(fd) + data = unsafe.Pointer(uintptr(data) + 4) } return b } diff --git a/libgo/go/syscall/syscall.go b/libgo/go/syscall/syscall.go index ff09711..7d42ad5 100644 --- a/libgo/go/syscall/syscall.go +++ b/libgo/go/syscall/syscall.go @@ -99,5 +99,8 @@ func (tv *Timeval) Nano() int64 { // use is a no-op, but the compiler cannot see that it is. // Calling use(p) ensures that p is kept live until that point. +// This was needed until Go 1.6 to call syscall.Syscall correctly. +// As of Go 1.6 the compiler handles that case automatically. +// The uses and definition of use can be removed early in the Go 1.7 cycle. //go:noescape func use(p unsafe.Pointer) diff --git a/libgo/go/syscall/syscall_linux_mips64x.go b/libgo/go/syscall/syscall_linux_mips64x.go new file mode 100644 index 0000000..c1d51b1 --- /dev/null +++ b/libgo/go/syscall/syscall_linux_mips64x.go @@ -0,0 +1,20 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux +// +build mips64 mips64le + +package syscall + +func (r *PtraceRegs) PC() uint64 { return r.Regs[64] } + +func (r *PtraceRegs) SetPC(pc uint64) { r.Regs[64] = pc } + +func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { + return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) +} + +func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) { + return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) +} diff --git a/libgo/go/syscall/syscall_linux_test.go b/libgo/go/syscall/syscall_linux_test.go index 40fce6d..4cabf6c 100644 --- a/libgo/go/syscall/syscall_linux_test.go +++ b/libgo/go/syscall/syscall_linux_test.go @@ -66,11 +66,11 @@ func TestLinuxDeathSignal(t *testing.T) { cmd.Env = []string{"GO_DEATHSIG_PARENT=1"} chldStdin, err := cmd.StdinPipe() if err != nil { - t.Fatal("failed to create new stdin pipe: %v", err) + t.Fatalf("failed to create new stdin pipe: %v", err) } chldStdout, err := cmd.StdoutPipe() if err != nil { - t.Fatal("failed to create new stdout pipe: %v", err) + t.Fatalf("failed to create new stdout pipe: %v", err) } cmd.Stderr = os.Stderr @@ -114,7 +114,7 @@ func deathSignalParent() { err := cmd.Start() if err != nil { - fmt.Fprintf(os.Stderr, "death signal parent error: %v\n") + fmt.Fprintf(os.Stderr, "death signal parent error: %v\n", err) os.Exit(1) } cmd.Wait() diff --git a/libgo/go/syscall/syscall_unix.go b/libgo/go/syscall/syscall_unix.go index 21bf6ea..c47050d 100644 --- a/libgo/go/syscall/syscall_unix.go +++ b/libgo/go/syscall/syscall_unix.go @@ -7,6 +7,7 @@ package syscall import ( + "internal/race" "runtime" "sync" "unsafe" @@ -210,24 +211,30 @@ func (s Signal) String() string { func Read(fd int, p []byte) (n int, err error) { n, err = read(fd, p) - if raceenabled { + if race.Enabled { if n > 0 { - raceWriteRange(unsafe.Pointer(&p[0]), n) + race.WriteRange(unsafe.Pointer(&p[0]), n) } if err == nil { - raceAcquire(unsafe.Pointer(&ioSync)) + race.Acquire(unsafe.Pointer(&ioSync)) } } + if msanenabled && n > 0 { + msanWrite(unsafe.Pointer(&p[0]), n) + } return } func Write(fd int, p []byte) (n int, err error) { - if raceenabled { - raceReleaseMerge(unsafe.Pointer(&ioSync)) + if race.Enabled { + race.ReleaseMerge(unsafe.Pointer(&ioSync)) } n, err = write(fd, p) - if raceenabled && n > 0 { - raceReadRange(unsafe.Pointer(&p[0]), n) + if race.Enabled && n > 0 { + race.ReadRange(unsafe.Pointer(&p[0]), n) + } + if msanenabled && n > 0 { + msanRead(unsafe.Pointer(&p[0]), n) } return } |