ipv4: work around FreeBSD 12 kernel running COMPAT_FREEBSD32

On FreeBSD 12 kernel running COMPAT_FREEBSD32, it looks like the system
call recvmsg always returns an incorrect​ length for the out-of-band
data. This change adjusts the length when it looks incorrect.

Fixes golang/go#30899.

Change-Id: Ibb0cbcf9b1f5f959279c20395916d47bd75d289c
Reviewed-on: https://go-review.googlesource.com/c/net/+/168077
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Mikio Hara
2019-03-18 05:31:15 +09:00
parent 9f648a60d9
commit 7a92b5139a
5 changed files with 26 additions and 3 deletions

View File

@@ -89,6 +89,12 @@ func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) {
n = 0
err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
}
if compatFreeBSD32 {
l := len(ms[0].OOB)
if 0 < ms[0].NN && ms[0].NN < l {
ms[0].NN = l
}
}
return n, err
}
}
@@ -152,6 +158,12 @@ func (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) {
n = 0
err = &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
}
if compatFreeBSD32 {
l := len(ms[0].OOB)
if 0 < ms[0].NN && ms[0].NN < l {
ms[0].NN = l
}
}
return n, err
}
}

View File

@@ -23,7 +23,8 @@ var (
errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH)
// See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
freebsdVersion uint32
freebsdVersion uint32
compatFreeBSD32 bool // 386 emulation on amd64
)
func boolint(b bool) int {

View File

@@ -46,6 +46,12 @@ func (c *packetHandler) ReadFrom(b []byte) (h *Header, p []byte, cm *ControlMess
return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
}
if m.NN > 0 {
if compatFreeBSD32 {
l := len(m.OOB)
if m.NN < l {
m.NN = l
}
}
cm = new(ControlMessage)
if err := cm.Parse(m.OOB[:m.NN]); err != nil {
return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}

View File

@@ -49,6 +49,12 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.
return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType}
}
if m.NN > 0 {
if compatFreeBSD32 {
l := len(m.OOB)
if m.NN < l {
m.NN = l
}
}
cm = new(ControlMessage)
if err := cm.Parse(m.OOB[:m.NN]); err != nil {
return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}

View File

@@ -13,8 +13,6 @@ import (
"golang.org/x/net/internal/socket"
)
var compatFreeBSD32 bool // 386 emulation on amd64
func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
var gr groupReq
if ifi != nil {