Skip to content

Commit 745c190

Browse files
Add IPv6 validation to parseCIDRv6 to prevent IPv4 CIDR panics
The parseCIDRv6 function now explicitly validates that the provided CIDR is IPv6, not IPv4. Previously, net.ParseCIDR() would accept IPv4 CIDRs, and To16() would return a non-nil value (IPv4-mapped IPv6), but the mask would only be 4 bytes. This caused a panic when the code tried to index ipnet.Mask[i] assuming a 16-byte mask. The fix adds two validation checks: 1. ip.To4() == nil (ensures it's not IPv4) 2. len(ipnet.Mask) == net.IPv6len (ensures 16-byte mask) Added unit test TestParseCIDRv6_RejectsIPv4 to verify the validation.
1 parent 35f14a9 commit 745c190

2 files changed

Lines changed: 25 additions & 1 deletion

File tree

cloudstack/resource_cloudstack_network.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,11 +541,19 @@ func parseCIDRv6(d *schema.ResourceData, specifyiprange bool) (map[string]string
541541
m := make(map[string]string, 4)
542542

543543
cidr := d.Get("ip6cidr").(string)
544-
_, ipnet, err := net.ParseCIDR(cidr)
544+
ip, ipnet, err := net.ParseCIDR(cidr)
545545
if err != nil {
546546
return nil, fmt.Errorf("Unable to parse cidr %s: %s", cidr, err)
547547
}
548548

549+
// Validate that this is actually an IPv6 CIDR
550+
if ip.To4() != nil {
551+
return nil, fmt.Errorf("ip6cidr must be an IPv6 CIDR, got IPv4: %s", cidr)
552+
}
553+
if len(ipnet.Mask) != net.IPv6len {
554+
return nil, fmt.Errorf("ip6cidr must be an IPv6 CIDR with 16-byte mask, got %d bytes: %s", len(ipnet.Mask), cidr)
555+
}
556+
549557
if gateway, ok := d.GetOk("ip6gateway"); ok {
550558
m["ip6gateway"] = gateway.(string)
551559
} else {

cloudstack/resource_cloudstack_network_unit_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,19 @@ func TestParseCIDRv6_SmallerPrefix(t *testing.T) {
133133
t.Errorf("Expected end IP %s, got %s", expectedEndIP, result["endipv6"])
134134
}
135135
}
136+
137+
func TestParseCIDRv6_RejectsIPv4(t *testing.T) {
138+
d := schema.TestResourceDataRaw(t, resourceCloudStackNetwork().Schema, map[string]interface{}{
139+
"ip6cidr": "10.0.0.0/24",
140+
})
141+
142+
_, err := parseCIDRv6(d, false)
143+
if err == nil {
144+
t.Fatal("parseCIDRv6 should reject IPv4 CIDR")
145+
}
146+
147+
expectedError := "ip6cidr must be an IPv6 CIDR, got IPv4"
148+
if err.Error()[:len(expectedError)] != expectedError {
149+
t.Errorf("Expected error message to start with '%s', got '%s'", expectedError, err.Error())
150+
}
151+
}

0 commit comments

Comments
 (0)