Commit 93da0b6e authored by Luca Bruno's avatar Luca Bruno Committed by Ian Lance Taylor

syscall: drop dummy byte for oob in unixgram SendmsgN

This commit relaxes SendmsgN behavior of introducing a dummy 1-byte
payload when sending ancillary-only messages.
The fake payload is not needed for SOCK_DGRAM type sockets, and actually
breaks interoperability with other fd-passing software (journald is one
known example). This introduces an additional check to avoid injecting
dummy payload in such case.

Full reference at https:/golang.org/issue/6476#issue-51285243

Fixes #6476

Change-Id: I19a974b4e7920e002bd0556259ab766572358520
Reviewed-on: https://go-review.googlesource.com/45872Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 5a7283f1
...@@ -19,7 +19,21 @@ import ( ...@@ -19,7 +19,21 @@ import (
// sockets. The SO_PASSCRED socket option is enabled on the sending // sockets. The SO_PASSCRED socket option is enabled on the sending
// socket for this to work. // socket for this to work.
func TestSCMCredentials(t *testing.T) { func TestSCMCredentials(t *testing.T) {
fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0) socketTypeTests := []struct {
socketType int
dataLen int
}{
{
syscall.SOCK_STREAM,
1,
}, {
syscall.SOCK_DGRAM,
0,
},
}
for _, tt := range socketTypeTests {
fds, err := syscall.Socketpair(syscall.AF_LOCAL, tt.socketType, 0)
if err != nil { if err != nil {
t.Fatalf("Socketpair: %v", err) t.Fatalf("Socketpair: %v", err)
} }
...@@ -72,7 +86,7 @@ func TestSCMCredentials(t *testing.T) { ...@@ -72,7 +86,7 @@ func TestSCMCredentials(t *testing.T) {
ucred.Gid = uint32(os.Getgid()) ucred.Gid = uint32(os.Getgid())
oob := syscall.UnixCredentials(&ucred) oob := syscall.UnixCredentials(&ucred)
// this is going to send a dummy byte // On SOCK_STREAM, this is internally going to send a dummy byte
n, oobn, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil) n, oobn, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
if err != nil { if err != nil {
t.Fatalf("WriteMsgUnix: %v", err) t.Fatalf("WriteMsgUnix: %v", err)
...@@ -92,8 +106,8 @@ func TestSCMCredentials(t *testing.T) { ...@@ -92,8 +106,8 @@ func TestSCMCredentials(t *testing.T) {
if flags != 0 { if flags != 0 {
t.Fatalf("ReadMsgUnix flags = 0x%x, want 0", flags) t.Fatalf("ReadMsgUnix flags = 0x%x, want 0", flags)
} }
if n != 1 { if n != tt.dataLen {
t.Fatalf("ReadMsgUnix n = %d, want 1 (dummy byte)", n) t.Fatalf("ReadMsgUnix n = %d, want %d", n, tt.dataLen)
} }
if oobn2 != oobn { if oobn2 != oobn {
// without SO_PASSCRED set on the socket, ReadMsgUnix will // without SO_PASSCRED set on the socket, ReadMsgUnix will
...@@ -116,4 +130,5 @@ func TestSCMCredentials(t *testing.T) { ...@@ -116,4 +130,5 @@ func TestSCMCredentials(t *testing.T) {
if *newUcred != ucred { if *newUcred != ucred {
t.Fatalf("ParseUnixCredentials = %+v, want %+v", newUcred, ucred) t.Fatalf("ParseUnixCredentials = %+v, want %+v", newUcred, ucred)
} }
}
} }
...@@ -537,8 +537,13 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from ...@@ -537,8 +537,13 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
} }
var dummy byte var dummy byte
if len(oob) > 0 { if len(oob) > 0 {
var sockType int
sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
if err != nil {
return
}
// receive at least one normal byte // receive at least one normal byte
if len(p) == 0 { if sockType != SOCK_DGRAM && len(p) == 0 {
iov.Base = &dummy iov.Base = &dummy
iov.SetLen(1) iov.SetLen(1)
} }
...@@ -584,8 +589,13 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) ...@@ -584,8 +589,13 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error)
} }
var dummy byte var dummy byte
if len(oob) > 0 { if len(oob) > 0 {
var sockType int
sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
if err != nil {
return 0, err
}
// send at least one normal byte // send at least one normal byte
if len(p) == 0 { if sockType != SOCK_DGRAM && len(p) == 0 {
iov.Base = &dummy iov.Base = &dummy
iov.SetLen(1) iov.SetLen(1)
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment