]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix shutdown races in catzs
authorAram Sargsyan <aram@isc.org>
Fri, 20 Oct 2023 10:45:35 +0000 (10:45 +0000)
committerArаm Sаrgsyаn <aram@isc.org>
Mon, 23 Oct 2023 08:21:39 +0000 (08:21 +0000)
The dns__catz_update_cb() does not expect that 'catzs->zones'
can become NULL during shutdown.

Add similar checks in the dns__catz_update_cb() and dns_catz_zone_get()
functions to protect from such a case. Also add an INSIST in the
dns_catz_zone_add() function to explicitly state that such a case
is not expected there, because that function is called only during a
reconfiguration.

lib/dns/catz.c
lib/dns/include/dns/catz.h

index 92149db4685d6bf8cf64871c4e05d05df16bedb6..5671f3c962106354da3f7253acc8b6d92ff35b9b 100644 (file)
@@ -897,6 +897,13 @@ dns_catz_zone_add(dns_catz_zones_t *catzs, const dns_name_t *name,
 
        LOCK(&catzs->lock);
 
+       /*
+        * This function is called only during a (re)configuration, while
+        * 'catzs->zones' can become NULL only during shutdown.
+        */
+       INSIST(catzs->zones != NULL);
+       INSIST(!atomic_load(&catzs->shuttingdown));
+
        result = isc_ht_find(catzs->zones, name->ndata, name->length,
                             (void **)&catz);
        switch (result) {
@@ -932,6 +939,10 @@ dns_catz_zone_get(dns_catz_zones_t *catzs, const dns_name_t *name) {
        REQUIRE(ISC_MAGIC_VALID(name, DNS_NAME_MAGIC));
 
        LOCK(&catzs->lock);
+       if (catzs->zones == NULL) {
+               UNLOCK(&catzs->lock);
+               return (NULL);
+       }
        result = isc_ht_find(catzs->zones, name->ndata, name->length,
                             (void **)&found);
        UNLOCK(&catzs->lock);
@@ -2241,6 +2252,11 @@ dns__catz_update_cb(void *data) {
         */
        dns_name_toregion(&updb->origin, &r);
        LOCK(&catzs->lock);
+       if (catzs->zones == NULL) {
+               UNLOCK(&catzs->lock);
+               result = ISC_R_SHUTTINGDOWN;
+               goto exit;
+       }
        result = isc_ht_find(catzs->zones, r.base, r.length, (void **)&oldcatz);
        is_active = (result == ISC_R_SUCCESS && oldcatz->active);
        UNLOCK(&catzs->lock);
index 826e8df093dbcc916e2b252a283e237a374b846c..5d9af5e0fa3766fa753b73ce87ca4fc5c377baad 100644 (file)
@@ -302,7 +302,8 @@ isc_result_t
 dns_catz_zone_add(dns_catz_zones_t *catzs, const dns_name_t *name,
                  dns_catz_zone_t **catzp);
 /*%<
- * Allocate a new catz named 'name' and put it in 'catzs' collection.
+ * Allocate a new catz named 'name' and put it in 'catzs' collection. This
+ * function is safe to call only during a (re)configuration.
  *
  * Requires:
  * \li 'catzs' is a valid dns_catz_zones_t.