summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Markwalder <tmark@isc.org>2014-09-11 15:56:24 -0400
committerThomas Markwalder <tmark@isc.org>2014-09-11 15:56:24 -0400
commit52eb3837610125d946e4b08bd4a799a67f33ef3e (patch)
tree95af5d49d5133bf702942c7f7a5989ca55f034ca
parent6429da6818bef05755e2a191b3d0de815e3939b8 (diff)
downloadisc-dhcp-52eb3837610125d946e4b08bd4a799a67f33ef3e.tar.gz
[v4_2] Added subnet address validation checks
Merges in rt32453.
-rw-r--r--RELNOTES6
-rw-r--r--server/confpars.c49
2 files changed, 53 insertions, 2 deletions
diff --git a/RELNOTES b/RELNOTES
index 1263967e..1f1afb7b 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -78,13 +78,17 @@ by Eric Young (eay@cryptsoft.com).
Also ISC_R_MULTIPLE has been removed as it is also deifned in bind.
[ISC-Bugs #37128]
+- Added checks in range6 and prefix6 statement parsing to ensure addresses
+ are within the declared. Thanks to Jiri Popelka at Red Hat for the bug
+ report and patch.
+ [ISC-Bugs #32453]
+
Changes since 4.2.7rc1
- None
Changes since 4.2.7b1
-
- Modify the linux and openwrt dhclient scripts to process information
from a stateless request. Thanks to Jiri Popelka at Red Hat for the
bug report and patch.
diff --git a/server/confpars.c b/server/confpars.c
index cc044f8f..89cbce54 100644
--- a/server/confpars.c
+++ b/server/confpars.c
@@ -3783,6 +3783,14 @@ parse_address_range6(struct parse *cfile, struct group *group) {
return;
}
+ /* Make sure starting address is within the subnet */
+ if (!addr_eq(group->subnet->net,
+ subnet_number(lo, group->subnet->netmask))) {
+ parse_warn(cfile, "range6 start address is outside the subnet");
+ skip_to_semi(cfile);
+ return;
+ }
+
/*
* See if we we're using range or CIDR notation or TEMPORARY
*/
@@ -3804,12 +3812,17 @@ parse_address_range6(struct parse *cfile, struct group *group) {
skip_to_semi(cfile);
return;
}
+ if (bits < group->subnet->prefix_len) {
+ parse_warn(cfile,
+ "network mask smaller than subnet mask");
+ skip_to_semi(cfile);
+ return;
+ }
if (!is_cidr_mask_valid(&lo, bits)) {
parse_warn(cfile, "network mask too short");
skip_to_semi(cfile);
return;
}
-
/*
* can be temporary (RFC 4941 like)
*/
@@ -3850,6 +3863,15 @@ parse_address_range6(struct parse *cfile, struct group *group) {
return;
}
+ /* Make sure ending address is within the subnet */
+ if (!addr_eq(group->subnet->net,
+ subnet_number(hi, group->subnet->netmask))) {
+ parse_warn(cfile,
+ "range6 end address is outside the subnet");
+ skip_to_semi(cfile);
+ return;
+ }
+
/*
* Convert our range to a set of CIDR networks.
*/
@@ -3903,10 +3925,29 @@ parse_prefix6(struct parse *cfile, struct group *group) {
if (!parse_ip6_addr(cfile, &lo)) {
return;
}
+
+ /* Make sure starting prefix is within the subnet */
+ if (!addr_eq(group->subnet->net,
+ subnet_number(lo, group->subnet->netmask))) {
+ parse_warn(cfile, "prefix6 start prefix"
+ " is outside the subnet");
+ skip_to_semi(cfile);
+ return;
+ }
+
if (!parse_ip6_addr(cfile, &hi)) {
return;
}
+ /* Make sure ending prefix is within the subnet */
+ if (!addr_eq(group->subnet->net,
+ subnet_number(hi, group->subnet->netmask))) {
+ parse_warn(cfile, "prefix6 end prefix"
+ " is outside the subnet");
+ skip_to_semi(cfile);
+ return;
+ }
+
/*
* Next is '/' number ';'.
*/
@@ -3929,9 +3970,15 @@ parse_prefix6(struct parse *cfile, struct group *group) {
parse_warn(cfile, "networks have 0 to 128 bits (exclusive)");
return;
}
+ if (bits < group->subnet->prefix_len) {
+ parse_warn(cfile, "network mask smaller than subnet mask");
+ skip_to_semi(cfile);
+ return;
+ }
if (!is_cidr_mask_valid(&lo, bits) ||
!is_cidr_mask_valid(&hi, bits)) {
parse_warn(cfile, "network mask too short");
+ skip_to_semi(cfile);
return;
}
token = next_token(NULL, NULL, cfile);