diff --git a/src/net/unixsock_linux_test.go b/src/net/unixsock_linux_test.go index d04007cef3..3c8fd85a9f 100644 --- a/src/net/unixsock_linux_test.go +++ b/src/net/unixsock_linux_test.go @@ -49,6 +49,23 @@ func TestUnixAutobindClose(t *testing.T) { ln.Close() } +func TestUnixAbstractLongNameNullStart(t *testing.T) { + // Create an abstract socket name that starts with a null byte ("\x00") + // whose length is the maximum of RawSockaddrUnix Path len + paddedAddr := make([]byte, len(syscall.RawSockaddrUnix{}.Path)) + copy(paddedAddr, "\x00abstract_test") + + la, err := ResolveUnixAddr("unix", string(paddedAddr)) + if err != nil { + t.Fatal(err) + } + c, err := ListenUnix("unix", la) + if err != nil { + t.Fatal(err) + } + defer c.Close() +} + func TestUnixgramLinuxAbstractLongName(t *testing.T) { if !testableNetwork("unixgram") { t.Skip("abstract unix socket long name test") diff --git a/src/net/unixsock_windows_test.go b/src/net/unixsock_windows_test.go index 511ba6f2df..c30916c838 100644 --- a/src/net/unixsock_windows_test.go +++ b/src/net/unixsock_windows_test.go @@ -10,6 +10,7 @@ import ( "internal/syscall/windows" "os" "reflect" + "syscall" "testing" ) @@ -69,6 +70,27 @@ func TestUnixConnLocalWindows(t *testing.T) { } } +func TestUnixAbstractLongNameNullStart(t *testing.T) { + if !windows.SupportUnixSocket() { + t.Skip("unix test") + } + + // Create an abstract socket name that starts with a null byte ("\x00") + // whose length is the maximum of RawSockaddrUnix Path len + paddedAddr := make([]byte, len(syscall.RawSockaddrUnix{}.Path)) + copy(paddedAddr, "\x00abstract_test") + + la, err := ResolveUnixAddr("unix", string(paddedAddr)) + if err != nil { + t.Fatal(err) + } + c, err := ListenUnix("unix", la) + if err != nil { + t.Fatal(err) + } + defer c.Close() +} + func TestModeSocket(t *testing.T) { if !windows.SupportUnixSocket() { t.Skip("unix test") diff --git a/src/syscall/syscall_linux.go b/src/syscall/syscall_linux.go index 57d84748fe..7e3443e106 100644 --- a/src/syscall/syscall_linux.go +++ b/src/syscall/syscall_linux.go @@ -550,7 +550,8 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { if n > len(sa.raw.Path) { return nil, 0, EINVAL } - if n == len(sa.raw.Path) && name[0] != '@' { + isAbstract := n > 0 && (name[0] == '@' || name[0] == '\x00') + if n == len(sa.raw.Path) && !isAbstract { return nil, 0, EINVAL } sa.raw.Family = AF_UNIX @@ -562,8 +563,7 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { if n > 0 { sl += _Socklen(n) + 1 } - if sa.raw.Path[0] == '@' || (sa.raw.Path[0] == 0 && sl > 3) { - // Check sl > 3 so we don't change unnamed socket behavior. + if isAbstract { sa.raw.Path[0] = 0 // Don't count trailing NUL for abstract address. sl-- diff --git a/src/syscall/syscall_windows.go b/src/syscall/syscall_windows.go index 344f6c325c..6bc2c5a6bb 100644 --- a/src/syscall/syscall_windows.go +++ b/src/syscall/syscall_windows.go @@ -858,7 +858,8 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) { if n > len(sa.raw.Path) { return nil, 0, EINVAL } - if n == len(sa.raw.Path) && name[0] != '@' { + isAbstract := n > 0 && (name[0] == '@' || name[0] == '\x00') + if n == len(sa.raw.Path) && !isAbstract { return nil, 0, EINVAL } sa.raw.Family = AF_UNIX @@ -870,8 +871,7 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) { if n > 0 { sl += int32(n) + 1 } - if sa.raw.Path[0] == '@' || (sa.raw.Path[0] == 0 && sl > 3) { - // Check sl > 3 so we don't change unnamed socket behavior. + if isAbstract { sa.raw.Path[0] = 0 // Don't count trailing NUL for abstract address. sl--