]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
properly range-check fields that do not allow 0
authorEvan Hunt <each@isc.org>
Tue, 14 Aug 2012 05:44:49 +0000 (22:44 -0700)
committerEvan Hunt <each@isc.org>
Tue, 14 Aug 2012 05:44:49 +0000 (22:44 -0700)
3362. [bug] Setting some option values to 0 in named.conf
could trigger an assertion failure on startup.
[RT #27730]

CHANGES
bin/tests/system/checkconf/clean.sh
bin/tests/system/checkconf/tests.sh
lib/bind9/check.c

diff --git a/CHANGES b/CHANGES
index d7cd933b6cd20cca9a266e3d1ba5d95841a26f67..ad8597bca1ab6731861c873c598e7d0e21909406 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+3362.  [bug]           Setting some option values to 0 in named.conf
+                       could trigger an assertion failure on startup.
+                       [RT #27730]
+
 3360.  [bug]           'host -w' could die.  [RT #18723]
 
 3359.  [bug]           An improperly-formed TSIG secret could cause a
index 2c5c83dd30b4982f934dad29307ea8b6566c2234..94e1b2d45871916f9bfcdb8870f33eb0cbbe6159 100644 (file)
@@ -16,4 +16,4 @@
 
 # $Id: clean.sh,v 1.1.4.2 2011/05/07 05:52:58 each Exp $
 
-rm -f good.conf.in good.conf.out
+rm -f good.conf.in good.conf.out badzero.conf
index a81195a8b138e402a5add80975fbae648b1fd7a3..f564fc23ee0c945f70408cabd2b1d86c004caaae 100644 (file)
@@ -56,5 +56,35 @@ $CHECKCONF dnssec.3 2>&1 | grep '.*' && ret=1
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
+echo "I: range checking fields that do not allow zero"
+ret=0
+for field in max-retry-time min-retry-time max-refresh-time min-refresh-time; do
+    cat > badzero.conf << EOF
+options {
+    $field 0;
+};
+EOF
+    $CHECKCONF badzero.conf > /dev/null 2>&1
+    [ $? -eq 1 ] || { echo "I: options $field failed" ; ret=1; }
+    cat > badzero.conf << EOF
+view dummy {
+    $field 0;
+};
+EOF
+    $CHECKCONF badzero.conf > /dev/null 2>&1
+    [ $? -eq 1 ] || { echo "I: view $field failed" ; ret=1; }
+    cat > badzero.conf << EOF
+zone dummy {
+    type slave;
+    masters { 0.0.0.0; };
+    $field 0;
+};
+EOF
+    $CHECKCONF badzero.conf > /dev/null 2>&1
+    [ $? -eq 1 ] || { echo "I: zone $field failed" ; ret=1; }
+done
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 echo "I:exit status: $status"
 exit $status
index 6ed67a91bf58864908e1ac15af0b8b56de554234..c69fb08b4af97e1cc0196c479b09784c5bee8ff4 100644 (file)
@@ -1156,6 +1156,29 @@ typedef struct {
        int allowed;
 } optionstable;
 
+static isc_result_t
+check_nonzero(const cfg_obj_t *options, isc_log_t *logctx) {
+       isc_result_t result = ISC_R_SUCCESS;
+       const cfg_obj_t *obj = NULL;
+       unsigned int i;
+
+       static const char *nonzero[] = { "max-retry-time", "min-retry-time",
+                                "max-refresh-time", "min-refresh-time" };
+       /*
+        * Check if value is zero.
+        */
+       for (i = 0; i < sizeof(nonzero) / sizeof(nonzero[0]); i++) {
+               obj = NULL;
+               if (cfg_map_get(options, nonzero[i], &obj) == ISC_R_SUCCESS &&
+                   cfg_obj_asuint32(obj) == 0) {
+                       cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                                   "'%s' must not be zero", nonzero[i]);
+                       result = ISC_R_FAILURE;
+               }
+       }
+       return (result);
+}
+
 static isc_result_t
 check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
               const cfg_obj_t *config, isc_symtab_t *symtab,
@@ -1165,7 +1188,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
        const char *zname;
        const char *typestr;
        unsigned int ztype;
-       const cfg_obj_t *zoptions;
+       const cfg_obj_t *zoptions, *goptions = NULL;
        const cfg_obj_t *obj = NULL;
        isc_result_t result = ISC_R_SUCCESS;
        isc_result_t tresult;
@@ -1238,9 +1261,11 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
        };
 
        zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
-
        zoptions = cfg_tuple_get(zconfig, "options");
 
+       if (config != NULL)
+               cfg_map_get(config, "options", &goptions);
+
        obj = NULL;
        (void)cfg_map_get(zoptions, "type", &obj);
        if (obj == NULL) {
@@ -1320,6 +1345,12 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
                        root = ISC_TRUE;
        }
 
+       /*
+        * Check if value is zero.
+        */
+       if (check_nonzero(zoptions, logctx) != ISC_R_SUCCESS)
+               result = ISC_R_FAILURE;
+
        /*
         * Look for inappropriate options for the given zone type.
         * Check that ACLs expand correctly.
@@ -1976,13 +2007,18 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
         * Check that forwarding is reasonable.
         */
        if (voptions == NULL) {
-               if (options != NULL)
+               if (options != NULL) {
                        if (check_forward(options, NULL,
                                          logctx) != ISC_R_SUCCESS)
                                result = ISC_R_FAILURE;
+                       if (check_nonzero(options, logctx) != ISC_R_SUCCESS)
+                               result = ISC_R_FAILURE;
+               }
        } else {
                if (check_forward(voptions, NULL, logctx) != ISC_R_SUCCESS)
                        result = ISC_R_FAILURE;
+               if (check_nonzero(voptions, logctx) != ISC_R_SUCCESS)
+                       result = ISC_R_FAILURE;
        }
 
        /*