diff --git a/src/net/unixsock_test.go b/src/net/unixsock_test.go index 489a29bc7d7..ac69a9abc6b 100644 --- a/src/net/unixsock_test.go +++ b/src/net/unixsock_test.go @@ -516,3 +516,57 @@ func TestUnixUnlink(t *testing.T) { l.Close() }) } + +func TestUnixLinuxAbstractLongName(t *testing.T) { + if runtime.GOOS != "linux" || !testableNetwork("unixgram") { + t.Skip("abstract unix socket long name test") + } + + // Create an abstract socket name whose length is exactly + // the maximum RawSockkaddrUnix Path len + rsu := syscall.RawSockaddrUnix{} + addrBytes := make([]byte, len(rsu.Path)) + copy(addrBytes, "@abstract_test") + addr := string(addrBytes) + + la, err := ResolveUnixAddr("unixgram", addr) + if err != nil { + t.Fatal(err) + } + c, err := ListenUnixgram("unixgram", la) + if err != nil { + t.Fatal(err) + } + defer c.Close() + + off := make(chan bool) + data := [5]byte{1, 2, 3, 4, 5} + go func() { + defer func() { off <- true }() + s, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_DGRAM, 0) + if err != nil { + t.Error(err) + return + } + defer syscall.Close(s) + rsa := &syscall.SockaddrUnix{Name: addr} + if err := syscall.Sendto(s, data[:], 0, rsa); err != nil { + t.Error(err) + return + } + }() + + <-off + b := make([]byte, 64) + c.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) + n, from, err := c.ReadFrom(b) + if err != nil { + t.Fatal(err) + } + if from != nil { + t.Fatalf("unexpected peer address: %v", from) + } + if !bytes.Equal(b[:n], data[:]) { + t.Fatalf("got %v; want %v", b[:n], data[:]) + } +} diff --git a/src/syscall/syscall_linux.go b/src/syscall/syscall_linux.go index 3c7d378d718..b42a8c1ba4f 100644 --- a/src/syscall/syscall_linux.go +++ b/src/syscall/syscall_linux.go @@ -295,7 +295,10 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) { func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { name := sa.Name n := len(name) - if n >= len(sa.raw.Path) { + if n > len(sa.raw.Path) { + return nil, 0, EINVAL + } + if n == len(sa.raw.Path) && name[0] != '@' { return nil, 0, EINVAL } sa.raw.Family = AF_UNIX