]> Cypherpunks repositories - gostls13.git/commitdiff
internal/routebsd: fix parsing network address of length zero
authorIan Lance Taylor <iant@golang.org>
Tue, 4 Feb 2025 23:11:42 +0000 (15:11 -0800)
committerGopher Robot <gobot@golang.org>
Wed, 5 Feb 2025 17:18:29 +0000 (09:18 -0800)
This applies CL 646555 from the net repository to this copy.

For #70528

Change-Id: Ib7e23accfa3f278392e7bdca6f8544b8f1395e7e
Reviewed-on: https://go-review.googlesource.com/c/go/+/646676
Reviewed-by: Damien Neil <dneil@google.com>
Auto-Submit: Ian Lance Taylor <iant@golang.org>
TryBot-Bypass: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
src/internal/routebsd/address.go
src/internal/routebsd/address_darwin_test.go

index 3368b22786eef7a6c3ae2202a2831dd586a6433a..75fafb1a15deb71715a8ee23f0a66d613afbc20a 100644 (file)
@@ -102,44 +102,52 @@ func (a *InetAddr) Family() int {
 // parseInetAddr parses b as an internet address for IPv4 or IPv6.
 func parseInetAddr(af int, b []byte) (Addr, error) {
        const (
-               off4 = 4 // offset of in_addr
-               off6 = 8 // offset of in6_addr
+               off4    = 4  // offset of in_addr
+               off6    = 8  // offset of in6_addr
+               ipv4Len = 4  // length of IPv4 address in bytes
+               ipv6Len = 16 // length of IPv6 address in bytes
        )
        switch af {
        case syscall.AF_INET:
-               if len(b) < (off4+1) || len(b) < int(b[0]) || b[0] == 0 {
+               if len(b) < (off4+1) || len(b) < int(b[0]) {
                        return nil, errInvalidAddr
                }
                sockAddrLen := int(b[0])
-               var ip [4]byte
-               n := off4 + 4
-               if sockAddrLen < n {
-                       n = sockAddrLen
+               var ip [ipv4Len]byte
+               if sockAddrLen != 0 {
+                       // Calculate how many bytes of the address to copy:
+                       // either full IPv4 length or the available length.
+                       n := off4 + ipv4Len
+                       if sockAddrLen < n {
+                               n = sockAddrLen
+                       }
+                       copy(ip[:], b[off4:n])
                }
-               copy(ip[:], b[off4:n])
                a := &InetAddr{
                        IP: netip.AddrFrom4(ip),
                }
                return a, nil
        case syscall.AF_INET6:
-               if len(b) < (off6+1) || len(b) < int(b[0]) || b[0] == 0 {
+               if len(b) < (off6+1) || len(b) < int(b[0]) {
                        return nil, errInvalidAddr
                }
+               var ip [ipv6Len]byte
                sockAddrLen := int(b[0])
-               n := off6 + 16
-               if sockAddrLen < n {
-                       n = sockAddrLen
-               }
-               var ip [16]byte
-               copy(ip[:], b[off6:n])
-               if ip[0] == 0xfe && ip[1]&0xc0 == 0x80 || ip[0] == 0xff && (ip[1]&0x0f == 0x01 || ip[1]&0x0f == 0x02) {
-                       // KAME based IPv6 protocol stack usually
-                       // embeds the interface index in the
-                       // interface-local or link-local address as
-                       // the kernel-internal form.
-                       id := int(bigEndian.Uint16(ip[2:4]))
-                       if id != 0 {
-                               ip[2], ip[3] = 0, 0
+               if sockaddrLen != 0 {
+                       n := off6 + ipv6Len
+                       if sockAddrLen < n {
+                               n = sockAddrLen
+                       }
+                       copy(ip[:], b[off6:n])
+                       if ip[0] == 0xfe && ip[1]&0xc0 == 0x80 || ip[0] == 0xff && (ip[1]&0x0f == 0x01 || ip[1]&0x0f == 0x02) {
+                               // KAME based IPv6 protocol stack usually
+                               // embeds the interface index in the
+                               // interface-local or link-local address as
+                               // the kernel-internal form.
+                               id := int(bigEndian.Uint16(ip[2:4]))
+                               if id != 0 {
+                                       ip[2], ip[3] = 0, 0
+                               }
                        }
                }
                // The kernel can provide an integer zone ID.
@@ -197,11 +205,11 @@ func parseKernelInetAddr(af int, b []byte) (int, Addr, error) {
        switch {
        case b[0] == syscall.SizeofSockaddrInet6:
                a := &InetAddr{
-                       IP: netip.AddrFrom16([16]byte(b[off6:off6+16])),
+                       IP: netip.AddrFrom16([16]byte(b[off6 : off6+16])),
                }
                return int(b[0]), a, nil
        case af == syscall.AF_INET6:
-               var ab[16]byte
+               var ab [16]byte
                if l-1 < off6 {
                        copy(ab[:], b[1:l])
                } else {
@@ -213,7 +221,7 @@ func parseKernelInetAddr(af int, b []byte) (int, Addr, error) {
                return int(b[0]), a, nil
        case b[0] == syscall.SizeofSockaddrInet4:
                a := &InetAddr{
-                       IP: netip.AddrFrom4([4]byte(b[off4:off4+4])),
+                       IP: netip.AddrFrom4([4]byte(b[off4 : off4+4])),
                }
                return int(b[0]), a, nil
        default: // an old fashion, AF_UNSPEC or unknown means AF_INET
@@ -251,16 +259,12 @@ func parseAddrs(attrs uint, b []byte) ([]Addr, error) {
                                }
                                b = b[l:]
                        case syscall.AF_INET, syscall.AF_INET6:
-                               // #70528: if the sockaddrlen is 0, no address to parse inside,
-                               // skip over the record.
-                               if b[0] > 0 {
-                                       af = int(b[1])
-                                       a, err := parseInetAddr(af, b)
-                                       if err != nil {
-                                               return nil, err
-                                       }
-                                       as[i] = a
+                               af = int(b[1])
+                               a, err := parseInetAddr(af, b)
+                               if err != nil {
+                                       return nil, err
                                }
+                               as[i] = a
                                l := roundup(int(b[0]))
                                if len(b) < l {
                                        return nil, errMessageTooShort
index 5f93e363a6fe902a9ad4870005fb6c1c96d0e98d..feffb1919aad340dc38405f13303bbb81a24b0e0 100644 (file)
@@ -108,7 +108,7 @@ var parseAddrsOnDarwinLittleEndianTests = []parseAddrsOnDarwinTest{
                        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
                },
                []Addr{
-                       nil,
+                       &InetAddr{IP: netip.AddrFrom16([16]byte{})},
                        &InetAddr{IP: netip.AddrFrom16([16]byte{0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x2f, 0x4b, 0xff, 0xfe, 0x09, 0x3b, 0xff})},
                        &InetAddr{IP: netip.AddrFrom16([16]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff})},
                        nil,