]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: allow abstract unix socket to use the full Path len
authorNicolas BRULEZ <n.brulez@gmail.com>
Tue, 26 Sep 2017 08:35:04 +0000 (10:35 +0200)
committerIan Lance Taylor <iant@golang.org>
Tue, 26 Sep 2017 15:08:03 +0000 (15:08 +0000)
The previous implementation forced all Unix socket to have a name
strictly shorter than len(sa.raw.Path) to allow a terminating NULL
byte to be added. This requirement does not apply to abstract socket
names under Linux, so for this case we allow the full length.

Fixes #21965

Change-Id: I1d1f58b6b6172d589428c7230cfeae984de78b4b
Reviewed-on: https://go-review.googlesource.com/66190
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/net/unixsock_test.go
src/syscall/syscall_linux.go

index 489a29bc7d7c224bc7cde5fc09e594d138cb8e1b..ac69a9abc6b0f1b9ef9a0845354f4a7e01358351 100644 (file)
@@ -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[:])
+       }
+}
index 3c7d378d7184582c25b958b092a0a88c2bb9c76a..b42a8c1ba4f141345be0953567ea9d61fd1ea3c3 100644 (file)
@@ -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