]> Cypherpunks repositories - gostls13.git/commitdiff
net/netip: check if address is v6 mapped in Is methods
authorRoland Shoemaker <bracewell@google.com>
Tue, 28 May 2024 20:26:31 +0000 (13:26 -0700)
committerGopher Robot <gobot@golang.org>
Tue, 4 Jun 2024 17:10:01 +0000 (17:10 +0000)
In all of the Is* methods, check if the address is a v6 mapped v4
address, and unmap it if so.

Thanks to Enze Wang of Alioth (@zer0yu) and Jianjun Chen of Zhongguancun
Lab (@chenjj) for reporting this issue.

Fixes #67680
Fixes CVE-2024-24790

Change-Id: I6bd03ca1a5d93a0b59027d861c84060967b265b0
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1460
Reviewed-by: Russ Cox <rsc@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/590316
Reviewed-by: David Chase <drchase@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/net/netip/inlining_test.go
src/net/netip/netip.go
src/net/netip/netip_test.go

index f5eb30df9091133018b0cf419d4258331a433d29..afd3e32bd23691f521d6dd48da5e45aed8e8f86a 100644 (file)
@@ -36,8 +36,6 @@ func TestInlining(t *testing.T) {
                "Addr.Is4",
                "Addr.Is4In6",
                "Addr.Is6",
-               "Addr.IsLoopback",
-               "Addr.IsMulticast",
                "Addr.IsInterfaceLocalMulticast",
                "Addr.IsValid",
                "Addr.IsUnspecified",
index 4b0a61dd9839409aefc5de4fec8bda86136d771e..57063eeb718a27e447ffe9d6f5310b3d4885ac82 100644 (file)
@@ -516,6 +516,10 @@ func (ip Addr) hasZone() bool {
 
 // IsLinkLocalUnicast reports whether ip is a link-local unicast address.
 func (ip Addr) IsLinkLocalUnicast() bool {
+       if ip.Is4In6() {
+               ip = ip.Unmap()
+       }
+
        // Dynamic Configuration of IPv4 Link-Local Addresses
        // https://datatracker.ietf.org/doc/html/rfc3927#section-2.1
        if ip.Is4() {
@@ -531,6 +535,10 @@ func (ip Addr) IsLinkLocalUnicast() bool {
 
 // IsLoopback reports whether ip is a loopback address.
 func (ip Addr) IsLoopback() bool {
+       if ip.Is4In6() {
+               ip = ip.Unmap()
+       }
+
        // Requirements for Internet Hosts -- Communication Layers (3.2.1.3 Addressing)
        // https://datatracker.ietf.org/doc/html/rfc1122#section-3.2.1.3
        if ip.Is4() {
@@ -546,6 +554,10 @@ func (ip Addr) IsLoopback() bool {
 
 // IsMulticast reports whether ip is a multicast address.
 func (ip Addr) IsMulticast() bool {
+       if ip.Is4In6() {
+               ip = ip.Unmap()
+       }
+
        // Host Extensions for IP Multicasting (4. HOST GROUP ADDRESSES)
        // https://datatracker.ietf.org/doc/html/rfc1112#section-4
        if ip.Is4() {
@@ -564,7 +576,7 @@ func (ip Addr) IsMulticast() bool {
 func (ip Addr) IsInterfaceLocalMulticast() bool {
        // IPv6 Addressing Architecture (2.7.1. Pre-Defined Multicast Addresses)
        // https://datatracker.ietf.org/doc/html/rfc4291#section-2.7.1
-       if ip.Is6() {
+       if ip.Is6() && !ip.Is4In6() {
                return ip.v6u16(0)&0xff0f == 0xff01
        }
        return false // zero value
@@ -572,6 +584,10 @@ func (ip Addr) IsInterfaceLocalMulticast() bool {
 
 // IsLinkLocalMulticast reports whether ip is a link-local multicast address.
 func (ip Addr) IsLinkLocalMulticast() bool {
+       if ip.Is4In6() {
+               ip = ip.Unmap()
+       }
+
        // IPv4 Multicast Guidelines (4. Local Network Control Block (224.0.0/24))
        // https://datatracker.ietf.org/doc/html/rfc5771#section-4
        if ip.Is4() {
@@ -600,6 +616,10 @@ func (ip Addr) IsGlobalUnicast() bool {
                return false
        }
 
+       if ip.Is4In6() {
+               ip = ip.Unmap()
+       }
+
        // Match package net's IsGlobalUnicast logic. Notably private IPv4 addresses
        // and ULA IPv6 addresses are still considered "global unicast".
        if ip.Is4() && (ip == IPv4Unspecified() || ip == AddrFrom4([4]byte{255, 255, 255, 255})) {
@@ -617,6 +637,10 @@ func (ip Addr) IsGlobalUnicast() bool {
 // ip is in 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, or fc00::/7. This is the
 // same as [net.IP.IsPrivate].
 func (ip Addr) IsPrivate() bool {
+       if ip.Is4In6() {
+               ip = ip.Unmap()
+       }
+
        // Match the stdlib's IsPrivate logic.
        if ip.Is4() {
                // RFC 1918 allocates 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16 as
index 4307df38bf424ec2f685ab33294a058ec7a933e9..ad0e7542082a23c962c605a627ca6120e8fce0a1 100644 (file)
@@ -599,10 +599,13 @@ func TestIPProperties(t *testing.T) {
                ilm6     = mustIP("ff01::1")
                ilmZone6 = mustIP("ff01::1%eth0")
 
-               private4a = mustIP("10.0.0.1")
-               private4b = mustIP("172.16.0.1")
-               private4c = mustIP("192.168.1.1")
-               private6  = mustIP("fd00::1")
+               private4a        = mustIP("10.0.0.1")
+               private4b        = mustIP("172.16.0.1")
+               private4c        = mustIP("192.168.1.1")
+               private6         = mustIP("fd00::1")
+               private6mapped4a = mustIP("::ffff:10.0.0.1")
+               private6mapped4b = mustIP("::ffff:172.16.0.1")
+               private6mapped4c = mustIP("::ffff:192.168.1.1")
        )
 
        tests := []struct {
@@ -626,6 +629,11 @@ func TestIPProperties(t *testing.T) {
                        ip:            unicast4,
                        globalUnicast: true,
                },
+               {
+                       name:          "unicast v6 mapped v4Addr",
+                       ip:            AddrFrom16(unicast4.As16()),
+                       globalUnicast: true,
+               },
                {
                        name:          "unicast v6Addr",
                        ip:            unicast6,
@@ -647,6 +655,12 @@ func TestIPProperties(t *testing.T) {
                        linkLocalMulticast: true,
                        multicast:          true,
                },
+               {
+                       name:               "multicast v6 mapped v4Addr",
+                       ip:                 AddrFrom16(multicast4.As16()),
+                       linkLocalMulticast: true,
+                       multicast:          true,
+               },
                {
                        name:               "multicast v6Addr",
                        ip:                 multicast6,
@@ -664,6 +678,11 @@ func TestIPProperties(t *testing.T) {
                        ip:               llu4,
                        linkLocalUnicast: true,
                },
+               {
+                       name:             "link-local unicast v6 mapped v4Addr",
+                       ip:               AddrFrom16(llu4.As16()),
+                       linkLocalUnicast: true,
+               },
                {
                        name:             "link-local unicast v6Addr",
                        ip:               llu6,
@@ -689,6 +708,11 @@ func TestIPProperties(t *testing.T) {
                        ip:       IPv6Loopback(),
                        loopback: true,
                },
+               {
+                       name:     "loopback v6 mapped v4Addr",
+                       ip:       AddrFrom16(IPv6Loopback().As16()),
+                       loopback: true,
+               },
                {
                        name:                    "interface-local multicast v6Addr",
                        ip:                      ilm6,
@@ -725,6 +749,24 @@ func TestIPProperties(t *testing.T) {
                        globalUnicast: true,
                        private:       true,
                },
+               {
+                       name:          "private v6 mapped v4Addr 10/8",
+                       ip:            private6mapped4a,
+                       globalUnicast: true,
+                       private:       true,
+               },
+               {
+                       name:          "private v6 mapped v4Addr 172.16/12",
+                       ip:            private6mapped4b,
+                       globalUnicast: true,
+                       private:       true,
+               },
+               {
+                       name:          "private v6 mapped v4Addr 192.168/16",
+                       ip:            private6mapped4c,
+                       globalUnicast: true,
+                       private:       true,
+               },
                {
                        name:        "unspecified v4Addr",
                        ip:          IPv4Unspecified(),