]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[v4_1_esv] Added subnet address validation checks
authorThomas Markwalder <tmark@isc.org>
Thu, 11 Sep 2014 20:01:22 +0000 (16:01 -0400)
committerThomas Markwalder <tmark@isc.org>
Thu, 11 Sep 2014 20:01:22 +0000 (16:01 -0400)
    Merges in rt32453.

RELNOTES
server/confpars.c

index e344e0ea565c3e8bf75574230785752a9af0199e..88f76a17ceba55d92c0b046375e99f5be1ec61f3 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -79,6 +79,11 @@ by Eric Young (eay@cryptsoft.com).
 - Server now supports a failover split value of 256.
   [ISC-Bugs] #36664]
 
+- 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.1-ESV-R10rc1
 
 - None
index ec912d803c435d476cd91d07ec9d6eae8dc19f74..2b392fe14bff844cda25b687ef62e16b6d3894fe 100644 (file)
@@ -3775,6 +3775,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
         */
@@ -3796,12 +3804,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)
                 */
@@ -3842,6 +3855,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.
                 */
@@ -3895,10 +3917,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 ';'.
         */
@@ -3921,9 +3962,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);