diff --git a/CHANGES b/CHANGES index a55037ce89..829bb8dd55 100644 --- 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] + 3361. [bug] "rndc signing -nsec3param" didn't work correctly when salt was set to '-' (no salt). [RT #30099] diff --git a/bin/tests/system/checkconf/clean.sh b/bin/tests/system/checkconf/clean.sh index 0e3c0e626b..94f09d9bc8 100644 --- a/bin/tests/system/checkconf/clean.sh +++ b/bin/tests/system/checkconf/clean.sh @@ -16,4 +16,4 @@ # $Id: clean.sh,v 1.2 2011/05/07 05:55:17 each Exp $ -rm -f good.conf.in good.conf.out +rm -f good.conf.in good.conf.out badzero.conf diff --git a/bin/tests/system/checkconf/tests.sh b/bin/tests/system/checkconf/tests.sh index 5298852279..795ab56d57 100644 --- a/bin/tests/system/checkconf/tests.sh +++ b/bin/tests/system/checkconf/tests.sh @@ -57,5 +57,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 diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 85a0cd1190..277e9b3a1b 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -1294,6 +1294,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, @@ -1303,7 +1326,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, const char *znamestr; 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; @@ -1384,10 +1407,14 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, { "passive", SLAVEZONE | STUBZONE | STREDIRECTZONE }, }; + znamestr = 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) { @@ -1476,6 +1503,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. @@ -2214,13 +2247,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; } /*