From dd73306509b4703011cbc6a8cc3d3667a58110d3 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 30 Nov 2022 18:44:37 +1100 Subject: [PATCH] Call dns_db_updatenotify_unregister earlier 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. (cherry picked from commit 35839e91d84f4c22f3554ff4b6dc53d20359621e) --- lib/dns/include/dns/zone.h | 3 +- lib/dns/rbtdb.c | 10 +------ lib/dns/zone.c | 60 ++++++++++++++++++++++---------------- 3 files changed, 38 insertions(+), 35 deletions(-) diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index cb5da5d046e..4bdc936949a 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -2610,7 +2610,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: * diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 36fce510244..b36cdf22059 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -1063,7 +1063,6 @@ free_rbtdb(dns_rbtdb_t *rbtdb, bool log, isc_event_t *event) { 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); @@ -1220,14 +1219,7 @@ free_rbtdb(dns_rbtdb_t *rbtdb, bool log, isc_event_t *event) { isc_file_munmap(rbtdb->mmap_location, (size_t)rbtdb->mmap_size); } - 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)); } diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 62c102b374f..21e71767e93 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -1938,6 +1938,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)); @@ -1964,6 +1989,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); } } @@ -1984,31 +2012,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 */ @@ -5375,6 +5378,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)) { @@ -17472,6 +17480,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); } -- 2.23.0