diff --git a/CHANGES b/CHANGES index 4c28c97316..a533cbe04f 100644 --- a/CHANGES +++ b/CHANGES @@ -8,7 +8,8 @@ 5958. [placeholder] -5957. [placeholder] +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 diff --git a/doc/notes/notes-current.rst b/doc/notes/notes-current.rst index e758ca8966..3411d2448d 100644 --- a/doc/notes/notes-current.rst +++ b/doc/notes/notes-current.rst @@ -15,7 +15,14 @@ Notes for BIND 9.19.5 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 e424835f0b..23e5c27d36 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -214,6 +214,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 @@ -3536,6 +3547,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); @@ -3726,6 +3738,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);