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 35839e91d8)
This commit is contained in:
Mark Andrews 2022-11-30 18:44:37 +11:00
parent 90822519eb
commit 6e2a33dd4c
3 changed files with 38 additions and 35 deletions

View file

@ -2654,7 +2654,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:
*

View file

@ -988,7 +988,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);
@ -1141,14 +1140,7 @@ free_rbtdb(dns_rbtdb_t *rbtdb, bool log, isc_event_t *event) {
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));
}

View file

@ -1968,6 +1968,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));
@ -1994,6 +2019,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);
}
}
@ -2014,31 +2042,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
*/
@ -5436,6 +5439,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))
{
@ -17746,6 +17754,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);
}