syscall: allow abstract unix socket to use the full Path len

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>
This commit is contained in:
Nicolas BRULEZ 2017-09-26 10:35:04 +02:00 committed by Ian Lance Taylor
parent c99cfd93a8
commit 08a1796671
2 changed files with 58 additions and 1 deletions

View 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[:])
}
}

View 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