-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FIX] Validate provided addresses are network addresses #1065
Conversation
pkg/ipnet/ipnet.go
Outdated
@@ -50,7 +50,7 @@ func (ipnet *IPNet) UnmarshalJSON(b []byte) (err error) { | |||
return errors.Wrap(err, "failed to Unmarshal string") | |||
} | |||
|
|||
ip, net, err := net.ParseCIDR(cidr) | |||
_, net, err := net.ParseCIDR(cidr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to preserve this return value so you can specify an IP within a subnet as well as the subnet itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wking
i tried to explain my reasoning in commit message 28494bb
before this change
ip0, ipnet0, _ := net.ParseCIDR("192.168.0.10/24")
ip0 => "192.168.0.10"
ipnet0 = > "192.168.0.0/24"
json.Unmarshal([]byte(`"192.168.0.10/24"`), &ipnet1)
ipnet1 => "192.168.0.10/24"
ipnet0 != ipnet1 when the input was the same...
which i think incorrect for expected bahavior
Line 16 in 63bdb7f
// IPNet wraps net.IPNet to get CIDR serialization. |
with this change
ip0, ipnet0, _ := net.ParseCIDR("192.168.0.10/24")
ip0 => "192.168.0.10"
ipnet0 = > "192.168.0.0/24"
json.Unmarshal([]byte(`"192.168.0.10/24"`), &ipnet1)
ipnet1 => "192.168.0.0/24"
ipnet0 == ipnet1 when the input was the same...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
which i think incorrect for expected bahavior
// IPNet wraps net.IPNet to get CIDR serialization.
I think you're focusing too much on ParseCIDR
's returned network, when the IPNet
wrapper is primarily wrapping net.IPNet
to add CIDR (de)serialization. Matching existing net.IPNet
behavior like round-tripping is part of that (e.g. see this play). If you decide you do need the lowest IP in an IPNet
range, you can always use yourIPNet.IP.Mask(yourIPNet.Mask)
to recover it (as shown in the play). Conversely, if we throw out the IP and jump straight to the masked IP on deserialization, we break round-tripping and there's no way to recover the initial IP offset.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so.
i think we should minic the behavior net.IPNet
String (serialize) and ParseCIDR (deserialize) for our json serialize/deserialize behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think we should minic the behavior
net.IPNet
String (serialize)...
Sounds good to me. And also JSON (de)serialization. But see here for where your implementation (at least as of 2a1bf26) diverges for JSON deserialization. While the master implementation (as of 7452eed) matches in all cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moving this commit to #1106.
This is not required to fix the validation issue.
pkg/ipnet/ipnet_test.go
Outdated
for _, test := range tests { | ||
t.Run(test.input, func(t *testing.T) { | ||
var ipNetOut IPNet | ||
err := json.Unmarshal([]byte(test.input), &ipNetOut) | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of switching on the err
under test, this should switch on the input test case. Something like:
if test.expErr == "" {
assert.NoError(t, err)
assert.Equal(t, text.exp, &ipNetOut)
} else {
asset.EqualError(t, err, test.expErr)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
85bacba
to
2a1bf26
Compare
2a1bf26
to
df680a1
Compare
pkg/validate/validate_test.go
Outdated
if tc.valid { | ||
assert.NoError(t, err) | ||
err = SubnetCIDR(&net.IPNet{IP: ip, Mask: cidr.Mask}) | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still switching on the returned error and not on a testcase property [edit: actually, this is different code, but same issue ;)]. That can cause false negatives, e.g. if ParseCIDR
fails to return an expected error, then we'll hit the err == nil
case and execute the tautological assert.NoError(t, err)
. I've pushed git://github.com/wking/openshift-installer.git subnet-cidr-test-fix
(4c9deae) with a fixup to switch on the expected error instead. Can you take a look and squash that into your commit if it looks good to you (or tell me why it doesn't look good ;)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before this change validation allowed CIDRs with network IP set to any IP address in the range. This change enforces that CIDR notation use network IP. example, ```yaml ... networking: machineCIDR: 192.168.126.10/24 ... ``` The installer now errors on `create cluster` ```console FATAL failed to fetch Terraform Variables: failed to load asset "Install Config": invalid "install-config.yaml" file: networking.machineCIDR: Invalid value: "192.168.126.10/24": invalid network address. got 192.168.126.10/24, expecting 192.168.126.0/24 ```
df680a1
to
5c29e90
Compare
/retest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
/retest |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: abhinavdahiya, wking The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/retest |
Before this change validation allowed CIDRs with network IP set to any IP address in the range.
This change enforces that CIDR notation use network IP.
example,
The installer now errors on
create cluster
FATAL failed to fetch Terraform Variables: failed to load asset "Install Config": invalid "install-config.yaml" file: networking.machineCIDR: Invalid value: "192.168.126.10/24": invalid network address. got 192.168.126.10/24, expecting 192.168.126.0/24
/cc @crawford @wking
xref: https://jira.coreos.com/browse/CORS-961
Fixes #1023