From 01209dfa49cf145f531756d0e9de57390ade147d Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 3 Feb 2021 11:10:20 +1100 Subject: [PATCH 1/5] Check SOA owner names in zone transfers An IXFR containing SOA records with owner names different than the transferred zone's origin can result in named serving a version of that zone without an SOA record at the apex. This causes a RUNTIME_CHECK assertion failure the next time such a zone is refreshed. Fix by immediately rejecting a zone transfer (either an incremental or non-incremental one) upon detecting an SOA record not placed at the apex of the transferred zone. --- lib/dns/xfrin.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index 5a950ae0eb..044acc09c3 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -498,6 +498,20 @@ xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, uint32_t ttl, FAIL(DNS_R_FORMERR); } + /* + * Immediately reject the entire transfer if the RR that is currently + * being processed is an SOA record that is not placed at the zone + * apex. + */ + if (rdata->type == dns_rdatatype_soa && + !dns_name_equal(&xfr->name, name)) { + char namebuf[DNS_NAME_FORMATSIZE]; + dns_name_format(name, namebuf, sizeof(namebuf)); + xfrin_log(xfr, ISC_LOG_DEBUG(3), "SOA name mismatch: '%s'", + namebuf); + FAIL(DNS_R_NOTZONETOP); + } + redo: switch (xfr->state) { case XFRST_SOAQUERY: From 2ca0bd882d389b6b1f8c0533560a78e456de4154 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Fri, 12 Feb 2021 14:51:28 +1100 Subject: [PATCH 2/5] Address inconsistencies in checking added RRsets loading_addrdataset() rejects SOA RRsets which are not at top of zone. addrdataset() should similarly reject such RRsets. --- lib/dns/rbtdb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index f9c93416ed..0e4872d1bc 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -6798,6 +6798,13 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); if (rbtdb->common.methods == &zone_methods) { + /* + * SOA records are only allowed at top of zone. + */ + if (rdataset->type == dns_rdatatype_soa && + node != rbtdb->origin_node) { + return (DNS_R_NOTZONETOP); + } RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 && (rdataset->type == dns_rdatatype_nsec3 || From 5318627227f90294ff24ef92ba87c77bd113de3f Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 25 Feb 2021 14:11:05 +1100 Subject: [PATCH 3/5] Unload a zone if a transfer breaks its SOA record If a zone transfer results in a zone not having any NS records, named stops serving it because such a zone is broken. Do the same if an incoming zone transfer results in a zone lacking an SOA record at the apex or containing more than one SOA record. --- lib/dns/zone.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 24d5849f61..00e6dd2f4e 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -17156,9 +17156,16 @@ again: if (soacount != 1) { dns_zone_log(zone, ISC_LOG_ERROR, "transferred zone " - "has %d SOA record%s", - soacount, - (soacount != 0) ? "s" : ""); + "has %d SOA records", + soacount); + if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) + { + zone->refresh = DNS_ZONE_DEFAULTREFRESH; + zone->retry = DNS_ZONE_DEFAULTRETRY; + } + DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); + zone_unload(zone); + goto next_master; } if (nscount == 0) { dns_zone_log(zone, ISC_LOG_ERROR, From 83ab536a305e0f43a042b7c3d5aa4d9149be3e46 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 3 Feb 2021 11:19:43 +1100 Subject: [PATCH 4/5] Add CHANGES entry for [GL #2467] --- CHANGES | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index ad7b586591..2798122996 100644 --- a/CHANGES +++ b/CHANGES @@ -45,7 +45,12 @@ 5616. [placeholder] -5615. [placeholder] +5615. [security] Insufficient IXFR checks could result in named serving a + zone without an SOA record at the apex, leading to a + RUNTIME_CHECK assertion failure when the zone was + subsequently refreshed. This has been fixed by adding an + owner name check for all SOA records which are included + in a zone transfer. (CVE-2021-25214) [GL #2467] 5614. [bug] Ensure all resources are properly cleaned up when a call to gss_accept_sec_context() fails. [GL #2620] From bd8a4a46dfe29596c52a1f18d3df640f38d4d513 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 3 Feb 2021 11:21:16 +1100 Subject: [PATCH 5/5] Add release note for [GL #2467] --- doc/notes/notes-current.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/notes/notes-current.rst b/doc/notes/notes-current.rst index 23f122f192..b559bccf92 100644 --- a/doc/notes/notes-current.rst +++ b/doc/notes/notes-current.rst @@ -14,7 +14,11 @@ Notes for BIND 9.17.12 Security Fixes ~~~~~~~~~~~~~~ -- None. +- A malformed incoming IXFR transfer could trigger an assertion failure + in ``named``, causing it to quit abnormally. (CVE-2021-25214) + + ISC would like to thank Greg Kuechle of SaskTel for bringing this + vulnerability to our attention. [GL #2467] Known Issues ~~~~~~~~~~~~