From c5e1c35e45821188aa996c15219ba4d30c1eedc4 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 8 Jul 2021 15:56:04 +1000 Subject: [PATCH] Silence untrusted loop bound on nsec3param.iterations 630 1. tainted_argument: Calling function dns_rdata_tostruct taints argument nsec3param.iterations. [show details] 631 result = dns_rdata_tostruct(nsec3rdata, &nsec3param, NULL); 2. Condition !!(result == 0), taking true branch. 3. Condition !!(result == 0), taking true branch. 632 RUNTIME_CHECK(result == ISC_R_SUCCESS); 633 634 dns_fixedname_init(&fixed); CID 281425 (#1 of 1): Untrusted loop bound (TAINTED_SCALAR) 4. tainted_data: Passing tainted expression nsec3param.iterations to dns_nsec3_hashname, which uses it as a loop boundary. [show details] Ensure that tainted values are properly sanitized, by checking that their values are within a permissible range. 635 result = dns_nsec3_hashname(&fixed, rawhash, &rhsize, vctx->origin, 636 vctx->origin, nsec3param.hash, 637 nsec3param.iterations, nsec3param.salt, 638 nsec3param.salt_length); --- lib/dns/zoneverify.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/dns/zoneverify.c b/lib/dns/zoneverify.c index 4ddb2430c5..fcd8b1ddb4 100644 --- a/lib/dns/zoneverify.c +++ b/lib/dns/zoneverify.c @@ -616,11 +616,11 @@ cleanup: } static isc_result_t -isoptout(const vctx_t *vctx, const dns_rdata_t *nsec3rdata, bool *optout) { +isoptout(const vctx_t *vctx, const dns_rdata_nsec3param_t *nsec3param, + bool *optout) { dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_nsec3_t nsec3; - dns_rdata_nsec3param_t nsec3param; dns_fixedname_t fixed; dns_name_t *hashname; isc_result_t result; @@ -628,14 +628,11 @@ isoptout(const vctx_t *vctx, const dns_rdata_t *nsec3rdata, bool *optout) { unsigned char rawhash[NSEC3_MAX_HASH_LENGTH]; size_t rhsize = sizeof(rawhash); - result = dns_rdata_tostruct(nsec3rdata, &nsec3param, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - dns_fixedname_init(&fixed); result = dns_nsec3_hashname(&fixed, rawhash, &rhsize, vctx->origin, - vctx->origin, nsec3param.hash, - nsec3param.iterations, nsec3param.salt, - nsec3param.salt_length); + vctx->origin, nsec3param->hash, + nsec3param->iterations, nsec3param->salt, + nsec3param->salt_length); if (result != ISC_R_SUCCESS) { zoneverify_log_error(vctx, "dns_nsec3_hashname(): %s", isc_result_totext(result)); @@ -708,7 +705,14 @@ verifynsec3(const vctx_t *vctx, const dns_name_t *name, return (ISC_R_SUCCESS); } - result = isoptout(vctx, rdata, &optout); + if (nsec3param.iterations > DNS_NSEC3_MAXITERATIONS) { + result = DNS_R_NSEC3ITERRANGE; + zoneverify_log_error(vctx, "verifynsec3: %s", + isc_result_totext(result)); + return (result); + } + + result = isoptout(vctx, &nsec3param, &optout); if (result != ISC_R_SUCCESS) { return (result); }