From 21e5646e53be5f75104a841ba6d936d9e7905707 Mon Sep 17 00:00:00 2001 From: Zxilly <31370133+Zxilly@users.noreply.github.com> Date: Mon, 5 May 2025 23:12:03 +0800 Subject: [PATCH] fix ECN control messages on big-endian architectures (#5105) * fix: correct select low bits when dealing with ecn * fix: revert action on ipv4 * chore: use uint8 Co-authored-by: Marten Seemann * fix: use binary to handle byte order --------- Co-authored-by: Marten Seemann --- sys_conn_oob.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sys_conn_oob.go b/sys_conn_oob.go index 974ff049..e8534708 100644 --- a/sys_conn_oob.go +++ b/sys_conn_oob.go @@ -197,6 +197,9 @@ func (c *oobConn) ReadPacket() (receivedPacket, error) { if hdr.Level == unix.IPPROTO_IP { switch hdr.Type { case msgTypeIPTOS: + if len(body) != 1 { + return receivedPacket{}, errors.New("invalid IPTOS size") + } p.ecn = protocol.ParseECNHeaderBits(body[0] & ecnMask) case ipv4PKTINFO: ip, ifIndex, ok := parseIPv4PktInfo(body) @@ -214,7 +217,11 @@ func (c *oobConn) ReadPacket() (receivedPacket, error) { if hdr.Level == unix.IPPROTO_IPV6 { switch hdr.Type { case unix.IPV6_TCLASS: - p.ecn = protocol.ParseECNHeaderBits(body[0] & ecnMask) + if len(body) != 4 { + return receivedPacket{}, errors.New("invalid IPV6_TCLASS size") + } + bits := uint8(binary.NativeEndian.Uint32(body)) & ecnMask + p.ecn = protocol.ParseECNHeaderBits(bits) case unix.IPV6_PKTINFO: // struct in6_pktinfo { // struct in6_addr ipi6_addr; /* src/dst IPv6 address */ @@ -326,6 +333,6 @@ func appendIPv6ECNMsg(b []byte, val protocol.ECN) []byte { // UnixRights uses the private `data` method, but I *think* this achieves the same goal. offset := startLen + unix.CmsgSpace(0) - b[offset] = val.ToHeaderBits() + binary.NativeEndian.PutUint32(b[offset:offset+dataLen], uint32(val.ToHeaderBits())) return b }