Skip to content

Commit

Permalink
[release-branch.go1.22] net/netip: check if address is v6 mapped in I…
Browse files Browse the repository at this point in the history
…s methods

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 #67682
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>
(cherry picked from commit f7f270c1621fdc7ee48e0487b2fac0356947d19b)
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1480
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/590296
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
  • Loading branch information
rolandshoemaker authored and gopherbot committed Jun 4, 2024
1 parent 7456575 commit 12d5810
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 7 deletions.
2 changes: 0 additions & 2 deletions src/net/netip/inlining_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
26 changes: 25 additions & 1 deletion src/net/netip/netip.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,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() {
Expand All @@ -523,6 +527,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() {
Expand All @@ -538,6 +546,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() {
Expand All @@ -556,14 +568,18 @@ 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
}

// 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() {
Expand Down Expand Up @@ -592,6 +608,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})) {
Expand All @@ -609,6 +629,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
Expand Down
50 changes: 46 additions & 4 deletions src/net/netip/netip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,10 +591,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 {
Expand All @@ -618,6 +621,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,
Expand All @@ -639,6 +647,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,
Expand All @@ -656,6 +670,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,
Expand All @@ -681,6 +700,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,
Expand Down Expand Up @@ -717,6 +741,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(),
Expand Down

0 comments on commit 12d5810

Please sign in to comment.