From 998765fea536daacfba96d8ed0a4855668d2e242 Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Tue, 13 Jun 2023 09:58:29 +0000 Subject: [PATCH 1/2] Fix catz db update callback registration logic error When a catalog zone is updated using AXFR, the zone database is changed, so it is required to unregister the update notification callback from the old database, and register it for the new one. Currently, here is the order of the steps happening in such scenario: 1. The zone.c:zone_startload() function registers the notify callback on the new database using dns_zone_catz_enable_db() 2. The callback, when called, notices that the new 'db' is different than 'catz->db', and unregisters the old callback for 'catz->db', marks that it's unregistered by setting 'catz->db_registered' to false, then it schedules an update if it isn't already scheduled. 3. The offloaded update process, after completing its job, notices that 'catz->db_registered' is false, and (re)registers the update callback for the current database it is working on. There is no harm here even if it was registered also on step 1, and we can't skip it, because this function can also be called "artificially" during a reconfiguration, and in that case the registration step is required here. A problem arises when before step 1 an update process was already in a running state, operating on the old database, and finishing its work only after step 2. As described in step 3, dns__catz_update_cb() notices that 'catz->db_registered' is false and registers the callback on the current database it is working on, which, at that state, is already obsolete and unused by the zone. When it detaches the database, the function which is responsible for its cleanup (e.g. free_rbtdb()) asserts because there is a registered update notify callback there. To fix the problem, instead of delaying the (re)registration to step 3, make sure that the new callback is registered and 'catz->db_registered' is accordingly marked on step 2. --- lib/dns/catz.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/dns/catz.c b/lib/dns/catz.c index bcf887e3bb..6bff6a8e48 100644 --- a/lib/dns/catz.c +++ b/lib/dns/catz.c @@ -2147,20 +2147,23 @@ dns_catz_dbupdate_callback(dns_db_t *db, void *fn_arg) { /* New zone came as AXFR */ if (catz->db != NULL && catz->db != db) { + /* Old db cleanup. */ if (catz->dbversion != NULL) { dns_db_closeversion(catz->db, &catz->dbversion, false); } dns_db_updatenotify_unregister( catz->db, dns_catz_dbupdate_callback, catz->catzs); dns_db_detach(&catz->db); - /* - * We're not registering db update callback, it will be - * registered at the end of dns__catz_update_cb() - */ catz->db_registered = false; } if (catz->db == NULL) { + /* New db registration. */ dns_db_attach(db, &catz->db); + result = dns_db_updatenotify_register( + db, dns_catz_dbupdate_callback, catz->catzs); + if (result == ISC_R_SUCCESS) { + catz->db_registered = true; + } } if (!catz->updatepending && !catz->updaterunning) { From 23f609ba5950d5aa59b8ecaffb96846a0f162082 Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Tue, 13 Jun 2023 10:52:05 +0000 Subject: [PATCH 2/2] Add a CHANGES note for [GL #4136] --- CHANGES | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGES b/CHANGES index 98d1e3d11f..04e5aad1ff 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +6193. [bug] Fix a catz db update notification callback registration + logic error, which could crash named when receiving an + AXFR update for a catalog zone while the previous update + process of the catalog zone was already running. + [GL #4136] + 6192. [placeholder] 6191. [placeholder]