Commit f853e9aa authored by Matthew Dempsky's avatar Matthew Dempsky Committed by Dave Cheney

syscall: Fix FD passing on OpenBSD

Fixes #3349.

R=bradfitz, dave, minux.ma
CC=golang-dev
https://golang.org/cl/7383056
parent d21b1922
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build linux darwin freebsd netbsd // +build linux darwin freebsd netbsd openbsd
package syscall_test package syscall_test
...@@ -149,3 +149,49 @@ func passFDChild() { ...@@ -149,3 +149,49 @@ func passFDChild() {
return return
} }
} }
// TestUnixRightsRoundtrip tests that UnixRights, ParseSocketControlMessage,
// and ParseUnixRights are able to successfully round-trip lists of file descriptors.
func TestUnixRightsRoundtrip(t *testing.T) {
testCases := [...][][]int{
{{42}},
{{1, 2}},
{{3, 4, 5}},
{{}},
{{1, 2}, {3, 4, 5}, {}, {7}},
}
for _, testCase := range testCases {
b := []byte{}
var n int
for _, fds := range testCase {
// Last assignment to n wins
n = len(b) + syscall.CmsgLen(4*len(fds))
b = append(b, syscall.UnixRights(fds...)...)
}
// Truncate b
b = b[:n]
scms, err := syscall.ParseSocketControlMessage(b)
if err != nil {
t.Fatalf("ParseSocketControlMessage: %v", err)
}
if len(scms) != len(testCase) {
t.Fatalf("expected %v SocketControlMessage; got scms = %#v", len(testCase), scms)
}
for i, scm := range scms {
gotFds, err := syscall.ParseUnixRights(&scm)
if err != nil {
t.Fatalf("ParseUnixRights: %v", err)
}
wantFds := testCase[i]
if len(gotFds) != len(wantFds) {
t.Fatalf("expected %v fds, got %#v", len(wantFds), gotFds)
}
for j, fd := range gotFds {
if fd != wantFds[j] {
t.Fatalf("expected fd %v, got %v", wantFds[j], fd)
}
}
}
}
}
...@@ -10,7 +10,7 @@ package syscall ...@@ -10,7 +10,7 @@ package syscall
import "unsafe" import "unsafe"
// Round the length of a raw sockaddr up to align it propery. // Round the length of a raw sockaddr up to align it properly.
func cmsgAlignOf(salen int) int { func cmsgAlignOf(salen int) int {
salign := sizeofPtr salign := sizeofPtr
// NOTE: It seems like 64-bit Darwin kernel still requires 32-bit // NOTE: It seems like 64-bit Darwin kernel still requires 32-bit
...@@ -18,9 +18,6 @@ func cmsgAlignOf(salen int) int { ...@@ -18,9 +18,6 @@ func cmsgAlignOf(salen int) int {
if darwinAMD64 { if darwinAMD64 {
salign = 4 salign = 4
} }
if salen == 0 {
return salign
}
return (salen + salign - 1) & ^(salign - 1) return (salen + salign - 1) & ^(salign - 1)
} }
...@@ -50,14 +47,15 @@ type SocketControlMessage struct { ...@@ -50,14 +47,15 @@ type SocketControlMessage struct {
// messages. // messages.
func ParseSocketControlMessage(b []byte) ([]SocketControlMessage, error) { func ParseSocketControlMessage(b []byte) ([]SocketControlMessage, error) {
var msgs []SocketControlMessage var msgs []SocketControlMessage
for len(b) >= CmsgLen(0) { i := 0
h, dbuf, err := socketControlMessageHeaderAndData(b) for i+CmsgLen(0) <= len(b) {
h, dbuf, err := socketControlMessageHeaderAndData(b[i:])
if err != nil { if err != nil {
return nil, err return nil, err
} }
m := SocketControlMessage{Header: *h, Data: dbuf[:int(h.Len)-cmsgAlignOf(SizeofCmsghdr)]} m := SocketControlMessage{Header: *h, Data: dbuf}
msgs = append(msgs, m) msgs = append(msgs, m)
b = b[cmsgAlignOf(int(h.Len)):] i += cmsgAlignOf(int(h.Len))
} }
return msgs, nil return msgs, nil
} }
...@@ -67,7 +65,7 @@ func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) { ...@@ -67,7 +65,7 @@ func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) {
if h.Len < SizeofCmsghdr || int(h.Len) > len(b) { if h.Len < SizeofCmsghdr || int(h.Len) > len(b) {
return nil, nil, EINVAL return nil, nil, EINVAL
} }
return h, b[cmsgAlignOf(SizeofCmsghdr):], nil return h, b[cmsgAlignOf(SizeofCmsghdr):h.Len], nil
} }
// UnixRights encodes a set of open file descriptors into a socket // UnixRights encodes a set of open file descriptors into a socket
......
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