Skip to content

Commit 1272bf9

Browse files
committed
ipv4: work around FreeBSD 11.3 or 12 kernel running COMPAT_FREEBSD32
On FreeBSD 11.3 or 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 and the running kernel is FreeBSD 11.3 or above. Fixes golang/go#30899. Change-Id: Ia58d8b4bd4caf3783d2e38161ee4afd1a64ca522 Reviewed-on: https://go-review.googlesource.com/c/net/+/168297 Run-TryBot: Mikio Hara <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 77544e6 commit 1272bf9

File tree

5 files changed

+26
-3
lines changed

5 files changed

+26
-3
lines changed

ipv4/batch.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) {
8989
n = 0
9090
err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
9191
}
92+
if compatFreeBSD32 && ms[0].NN > 0 {
93+
adjustFreeBSD32(&ms[0])
94+
}
9295
return n, err
9396
}
9497
}
@@ -152,6 +155,9 @@ func (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) {
152155
n = 0
153156
err = &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
154157
}
158+
if compatFreeBSD32 && ms[0].NN > 0 {
159+
adjustFreeBSD32(&ms[0])
160+
}
155161
return n, err
156162
}
157163
}

ipv4/helper.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"errors"
99
"net"
1010
"runtime"
11+
12+
"golang.org/x/net/internal/socket"
1113
)
1214

1315
var (
@@ -23,9 +25,20 @@ var (
2325
errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH)
2426

2527
// See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
26-
freebsdVersion uint32
28+
freebsdVersion uint32
29+
compatFreeBSD32 bool // 386 emulation on amd64
2730
)
2831

32+
// See golang.org/issue/30899.
33+
func adjustFreeBSD32(m *socket.Message) {
34+
if freebsdVersion >= 1103000 {
35+
l := (m.NN + 4 - 1) &^ (4 - 1)
36+
if m.NN < l && l <= len(m.OOB) {
37+
m.NN = l
38+
}
39+
}
40+
}
41+
2942
func boolint(b bool) int {
3043
if b {
3144
return 1

ipv4/packet.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ func (c *packetHandler) ReadFrom(b []byte) (h *Header, p []byte, cm *ControlMess
4646
return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
4747
}
4848
if m.NN > 0 {
49+
if compatFreeBSD32 {
50+
adjustFreeBSD32(&m)
51+
}
4952
cm = new(ControlMessage)
5053
if err := cm.Parse(m.OOB[:m.NN]); err != nil {
5154
return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}

ipv4/payload_cmsg.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.
4949
return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType}
5050
}
5151
if m.NN > 0 {
52+
if compatFreeBSD32 {
53+
adjustFreeBSD32(&m)
54+
}
5255
cm = new(ControlMessage)
5356
if err := cm.Parse(m.OOB[:m.NN]); err != nil {
5457
return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}

ipv4/sys_ssmreq.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ import (
1313
"golang.org/x/net/internal/socket"
1414
)
1515

16-
var compatFreeBSD32 bool // 386 emulation on amd64
17-
1816
func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
1917
var gr groupReq
2018
if ifi != nil {

0 commit comments

Comments
 (0)