diff --git a/CHANGES b/CHANGES index e8ea8e1e60..059cc4a1b6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +5957. [security] Prevent excessive resource use while processing large + delegations. (CVE-2022-2795) [GL #3394] + 5956. [func] Make RRL code treat all QNAMEs that are subject to wildcard processing within a given zone as the same name. [GL #3459] diff --git a/doc/notes/notes-current.rst b/doc/notes/notes-current.rst index 306a87ccbb..020cfd08ba 100644 --- a/doc/notes/notes-current.rst +++ b/doc/notes/notes-current.rst @@ -15,7 +15,14 @@ Notes for BIND 9.18.7 Security Fixes ~~~~~~~~~~~~~~ -- None. +- Previously, there was no limit to the number of database lookups + performed while processing large delegations, which could be abused to + severely impact the performance of :iscman:`named` running as a + recursive resolver. This has been fixed. (CVE-2022-2795) + + ISC would like to thank Yehuda Afek from Tel-Aviv University and Anat + Bremler-Barr & Shani Stajnrod from Reichman University for bringing + this vulnerability to our attention. :gl:`#3394` Known Issues ~~~~~~~~~~~~ diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 8883008420..e7437656b6 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -211,6 +211,17 @@ */ #define NS_FAIL_LIMIT 4 #define NS_RR_LIMIT 5 +/* + * IP address lookups are performed for at most NS_PROCESSING_LIMIT NS RRs in + * any NS RRset encountered, to avoid excessive resource use while processing + * large delegations. + */ +#define NS_PROCESSING_LIMIT 20 + +STATIC_ASSERT(NS_PROCESSING_LIMIT > NS_RR_LIMIT, + "The maximum number of NS RRs processed for each delegation " + "(NS_PROCESSING_LIMIT) must be larger than the large delegation " + "threshold (NS_RR_LIMIT)."); /* Hash table for zone counters */ #ifndef RES_DOMAIN_HASH_BITS @@ -3538,6 +3549,7 @@ fctx_getaddresses(fetchctx_t *fctx, bool badcache) { bool need_alternate = false; bool all_spilled = true; unsigned int no_addresses = 0; + unsigned int ns_processed = 0; FCTXTRACE5("getaddresses", "fctx->depth=", fctx->depth); @@ -3728,6 +3740,11 @@ normal_nses: dns_rdata_reset(&rdata); dns_rdata_freestruct(&ns); + + if (++ns_processed >= NS_PROCESSING_LIMIT) { + result = ISC_R_NOMORE; + break; + } } if (result != ISC_R_NOMORE) { return (result);