]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[master] Added subnet address validation checks
authorThomas Markwalder <tmark@isc.org>
Thu, 11 Sep 2014 19:45:10 +0000 (15:45 -0400)
committerThomas Markwalder <tmark@isc.org>
Thu, 11 Sep 2014 19:45:10 +0000 (15:45 -0400)
    Merges in rt32453.

RELNOTES
server/confpars.c

index 09c03e9173f4b38c6e542872456c57c239eedf6c..8cb0f494fe323043621eba91502408c5d1bf9e09 100644 (file)
--- 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
index 1f7cf73ddc1f2add46373332ff3b505260a1799a..006528af189bab36159766e9622786a4ef96c3b5 100644 (file)
@@ -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);