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 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux darwin freebsd netbsd
// +build linux darwin freebsd netbsd openbsd
package syscall_test
......@@ -149,3 +149,49 @@ func passFDChild() {
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
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 {
salign := sizeofPtr
// NOTE: It seems like 64-bit Darwin kernel still requires 32-bit
......@@ -18,9 +18,6 @@ func cmsgAlignOf(salen int) int {
if darwinAMD64 {
salign = 4
}
if salen == 0 {
return salign
}
return (salen + salign - 1) & ^(salign - 1)
}
......@@ -50,14 +47,15 @@ type SocketControlMessage struct {
// messages.
func ParseSocketControlMessage(b []byte) ([]SocketControlMessage, error) {
var msgs []SocketControlMessage
for len(b) >= CmsgLen(0) {
h, dbuf, err := socketControlMessageHeaderAndData(b)
i := 0
for i+CmsgLen(0) <= len(b) {
h, dbuf, err := socketControlMessageHeaderAndData(b[i:])
if err != nil {
return nil, err
}
m := SocketControlMessage{Header: *h, Data: dbuf[:int(h.Len)-cmsgAlignOf(SizeofCmsghdr)]}
m := SocketControlMessage{Header: *h, Data: dbuf}
msgs = append(msgs, m)
b = b[cmsgAlignOf(int(h.Len)):]
i += cmsgAlignOf(int(h.Len))
}
return msgs, nil
}
......@@ -67,7 +65,7 @@ func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) {
if h.Len < SizeofCmsghdr || int(h.Len) > len(b) {
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
......
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