From: Thomas Markwalder Date: Thu, 11 Sep 2014 19:45:10 +0000 (-0400) Subject: [master] Added subnet address validation checks X-Git-Tag: v4_3_2.pre-beta~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bd49432ff42d9b423319cebe25831f954ab63b81;p=thirdparty%2Fdhcp.git [master] Added subnet address validation checks Merges in rt32453. --- diff --git a/RELNOTES b/RELNOTES index 09c03e917..8cb0f494f 100644 --- a/RELNOTES +++ b/RELNOTES @@ -91,6 +91,11 @@ 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.3.1b1 - Modify the linux and openwrt dhclient scripts to process information diff --git a/server/confpars.c b/server/confpars.c index 1f7cf73dd..006528af1 100644 --- a/server/confpars.c +++ b/server/confpars.c @@ -3962,6 +3962,14 @@ parse_address_range6(struct parse *cfile, 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; + } + /* * zero out the net entry in case we use it */ @@ -3990,13 +3998,17 @@ parse_address_range6(struct parse *cfile, 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(&net.cidrnet.lo_addr, bits)) { parse_warn(cfile, "network mask too short"); skip_to_semi(cfile); return; } - /* * can be temporary (RFC 4941 like) */ @@ -4037,6 +4049,15 @@ parse_address_range6(struct parse *cfile, 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. */ @@ -4111,10 +4132,29 @@ parse_prefix6(struct parse *cfile, 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 ';'. */ @@ -4137,9 +4177,15 @@ parse_prefix6(struct parse *cfile, 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);