]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Call dns_db_updatenotify_unregister earlier
authorMark Andrews <marka@isc.org>
Wed, 30 Nov 2022 07:44:37 +0000 (18:44 +1100)
committerMark Andrews <marka@isc.org>
Tue, 6 Dec 2022 22:04:08 +0000 (09:04 +1100)
dns_db_updatenotify_unregister needed to be called earlier to ensure
that listener->onupdate_arg always points to a valid object.  The
existing lazy cleanup in rbtdb_free did not ensure that.

lib/dns/include/dns/zone.h
lib/dns/rbtdb.c
lib/dns/zone.c

index 8cf4cc3aaaa493354b0cf6d0b1d1f7dcdaa27105..a029c6e43fd2241c24fd508afd5efbd46dc87f5a 100644 (file)
@@ -2621,7 +2621,8 @@ dns_zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs);
 void
 dns_zone_catz_disable(dns_zone_t *zone);
 /*%<
- * Disable zone as catalog zone, if it is one.
+ * Disable zone as catalog zone, if it is one.  Also disables any
+ * registered callbacks for the catalog zone.
  *
  * Requires:
  *
index cf8170e874b7dffb2f636f331fa622b0d5f18bbb..15732ca87b27f740239e7cbe9f0333d35d85e629 100644 (file)
@@ -1112,7 +1112,6 @@ free_rbtdb(dns_rbtdb_t *rbtdb, bool log) {
        char buf[DNS_NAME_FORMATSIZE];
        dns_rbt_t **treep;
        isc_time_t start;
-       dns_dbonupdatelistener_t *listener, *listener_next;
 
        if (IS_CACHE(rbtdb) && rbtdb->common.rdclass == dns_rdataclass_in) {
                overmem((dns_db_t *)rbtdb, (bool)-1);
@@ -1253,14 +1252,7 @@ free_rbtdb(dns_rbtdb_t *rbtdb, bool log) {
        rbtdb->common.impmagic = 0;
        isc_mem_detach(&rbtdb->hmctx);
 
-       for (listener = ISC_LIST_HEAD(rbtdb->common.update_listeners);
-            listener != NULL; listener = listener_next)
-       {
-               listener_next = ISC_LIST_NEXT(listener, link);
-               ISC_LIST_UNLINK(rbtdb->common.update_listeners, listener, link);
-               isc_mem_put(rbtdb->common.mctx, listener,
-                           sizeof(dns_dbonupdatelistener_t));
-       }
+       INSIST(ISC_LIST_EMPTY(rbtdb->common.update_listeners));
 
        isc_mem_putanddetach(&rbtdb->common.mctx, rbtdb, sizeof(*rbtdb));
 }
index fb718151cc377b2bf8d21dc62859478269d3a7d1..bab33f390d6e3ae5c75333d406478d42cb345385 100644 (file)
@@ -1981,6 +1981,31 @@ dns_zone_rpz_disable_db(dns_zone_t *zone, dns_db_t *db) {
                                             zone->rpzs->zones[zone->rpz_num]);
 }
 
+/*
+ * If a zone is a catalog zone, attach it to update notification in database.
+ */
+void
+dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db) {
+       REQUIRE(DNS_ZONE_VALID(zone));
+       REQUIRE(db != NULL);
+
+       if (zone->catzs != NULL) {
+               dns_db_updatenotify_register(db, dns_catz_dbupdate_callback,
+                                            zone->catzs);
+       }
+}
+
+static void
+dns_zone_catz_disable_db(dns_zone_t *zone, dns_db_t *db) {
+       REQUIRE(DNS_ZONE_VALID(zone));
+       REQUIRE(db != NULL);
+
+       if (zone->catzs != NULL) {
+               dns_db_updatenotify_unregister(db, dns_catz_dbupdate_callback,
+                                              zone->catzs);
+       }
+}
+
 static void
 zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) {
        REQUIRE(DNS_ZONE_VALID(zone));
@@ -2007,6 +2032,9 @@ zone_catz_disable(dns_zone_t *zone) {
        REQUIRE(DNS_ZONE_VALID(zone));
 
        if (zone->catzs != NULL) {
+               if (zone->db != NULL) {
+                       dns_zone_catz_disable_db(zone, zone->db);
+               }
                dns_catz_catzs_detach(&zone->catzs);
        }
 }
@@ -2027,31 +2055,6 @@ dns_zone_catz_is_enabled(dns_zone_t *zone) {
        return (zone->catzs != NULL);
 }
 
-/*
- * If a zone is a catalog zone, attach it to update notification in database.
- */
-void
-dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db) {
-       REQUIRE(DNS_ZONE_VALID(zone));
-       REQUIRE(db != NULL);
-
-       if (zone->catzs != NULL) {
-               dns_db_updatenotify_register(db, dns_catz_dbupdate_callback,
-                                            zone->catzs);
-       }
-}
-
-static void
-dns_zone_catz_disable_db(dns_zone_t *zone, dns_db_t *db) {
-       REQUIRE(DNS_ZONE_VALID(zone));
-       REQUIRE(db != NULL);
-
-       if (zone->catzs != NULL) {
-               dns_db_updatenotify_unregister(db, dns_catz_dbupdate_callback,
-                                              zone->catzs);
-       }
-}
-
 /*
  * Set catalog zone ownership of the zone
  */
@@ -5456,6 +5459,11 @@ cleanup:
                           isc_result_totext(result));
        }
 
+       if (result != ISC_R_SUCCESS) {
+               dns_zone_rpz_disable_db(zone, db);
+               dns_zone_catz_disable_db(zone, db);
+       }
+
        for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL;
             inc = ISC_LIST_HEAD(zone->newincludes))
        {
@@ -17706,6 +17714,8 @@ static void
 zone_detachdb(dns_zone_t *zone) {
        REQUIRE(zone->db != NULL);
 
+       dns_zone_rpz_disable_db(zone, zone->db);
+       dns_zone_catz_disable_db(zone, zone->db);
        dns_db_detach(&zone->db);
 }