From 6f1f5fc307c2513d31cda94ef8cc47aa5efeaf88 Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Fri, 9 Jun 2023 07:13:27 +0000 Subject: [PATCH] Fix a data race between the dns_zone and dns_catz modules The dns_zone_catz_enable_db() and dns_zone_catz_disable_db() functions can race with similar operations in the catz module because there is no synchronization between the threads. Add catz functions which use the view's catalog zones' lock when registering/unregistering the database update notify callback, and use those functions in the dns_zone module, instead of doing it directly. --- lib/dns/catz.c | 20 ++++++++++++++++++++ lib/dns/include/dns/catz.h | 20 ++++++++++++++++++++ lib/dns/zone.c | 6 ++---- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/lib/dns/catz.c b/lib/dns/catz.c index 6bff6a8e48..4dfa2fac3e 100644 --- a/lib/dns/catz.c +++ b/lib/dns/catz.c @@ -2191,6 +2191,26 @@ cleanup: return (result); } +void +dns_catz_dbupdate_unregister(dns_db_t *db, dns_catz_zones_t *catzs) { + REQUIRE(DNS_DB_VALID(db)); + REQUIRE(DNS_CATZ_ZONES_VALID(catzs)); + + LOCK(&catzs->lock); + dns_db_updatenotify_unregister(db, dns_catz_dbupdate_callback, catzs); + UNLOCK(&catzs->lock); +} + +void +dns_catz_dbupdate_register(dns_db_t *db, dns_catz_zones_t *catzs) { + REQUIRE(DNS_DB_VALID(db)); + REQUIRE(DNS_CATZ_ZONES_VALID(catzs)); + + LOCK(&catzs->lock); + dns_db_updatenotify_register(db, dns_catz_dbupdate_callback, catzs); + UNLOCK(&catzs->lock); +} + static bool catz_rdatatype_is_processable(const dns_rdatatype_t type) { return (!dns_rdatatype_isdnssec(type) && type != dns_rdatatype_cds && diff --git a/lib/dns/include/dns/catz.h b/lib/dns/include/dns/catz.h index 394adad24e..16aff90469 100644 --- a/lib/dns/include/dns/catz.h +++ b/lib/dns/include/dns/catz.h @@ -354,6 +354,26 @@ dns_catz_dbupdate_callback(dns_db_t *db, void *fn_arg); * \li 'fn_arg' is not NULL (casted to dns_catz_zones_t*). */ +void +dns_catz_dbupdate_unregister(dns_db_t *db, dns_catz_zones_t *catzs); +/*%< + * Register the catalog zone database update notify callback. + * + * Requires: + * \li 'db' is a valid database. + * \li 'catzs' is valid. + */ + +void +dns_catz_dbupdate_register(dns_db_t *db, dns_catz_zones_t *catzs); +/*%< + * Unregister the catalog zone database update notify callback. + * + * Requires: + * \li 'db' is a valid database. + * \li 'catzs' is valid. + */ + void dns_catz_prereconfig(dns_catz_zones_t *catzs); /*%< diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 983b659b8b..68e29f8c93 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -1939,8 +1939,7 @@ dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db) { REQUIRE(db != NULL); if (zone->catzs != NULL) { - dns_db_updatenotify_register(db, dns_catz_dbupdate_callback, - zone->catzs); + dns_catz_dbupdate_register(db, zone->catzs); } } @@ -1950,8 +1949,7 @@ dns_zone_catz_disable_db(dns_zone_t *zone, dns_db_t *db) { REQUIRE(db != NULL); if (zone->catzs != NULL) { - dns_db_updatenotify_unregister(db, dns_catz_dbupdate_callback, - zone->catzs); + dns_catz_dbupdate_unregister(db, zone->catzs); } }