diff options
author | Thomas Markwalder <tmark@isc.org> | 2014-09-11 15:56:24 -0400 |
---|---|---|
committer | Thomas Markwalder <tmark@isc.org> | 2014-09-11 15:56:24 -0400 |
commit | 52eb3837610125d946e4b08bd4a799a67f33ef3e (patch) | |
tree | 95af5d49d5133bf702942c7f7a5989ca55f034ca | |
parent | 6429da6818bef05755e2a191b3d0de815e3939b8 (diff) | |
download | isc-dhcp-52eb3837610125d946e4b08bd4a799a67f33ef3e.tar.gz |
[v4_2] Added subnet address validation checks
Merges in rt32453.
-rw-r--r-- | RELNOTES | 6 | ||||
-rw-r--r-- | server/confpars.c | 49 |
2 files changed, 53 insertions, 2 deletions
@@ -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); |