From 6e08307bc8bbe64afa2af891c2b570740a454e63 Mon Sep 17 00:00:00 2001 From: Diego Fronza Date: Tue, 6 Apr 2021 16:29:25 -0300 Subject: [PATCH] Resolve TSAN data race in zone_maintenance Fix race between zone_maintenance and dns_zone_notifyreceive functions, zone_maintenance was attempting to read a zone flag calling DNS_ZONE_FLAG(zone, flag) while dns_zone_notifyreceive was updating a flag in the same zone calling DNS_ZONE_SETFLAG(zone, ...). The code reading the flag in zone_maintenance was not protected by the zone's lock, to avoid a race the zone's lock is now being acquired before an attempt to read the zone flag is made. --- lib/dns/zone.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 4f98f38a6a..c9bca4bd94 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -11063,6 +11063,7 @@ zone_maintenance(dns_zone_t *zone) { isc_time_t now; isc_result_t result; bool dumping, load_pending, viewok; + bool need_notify; REQUIRE(DNS_ZONE_VALID(zone)); ENTER; @@ -11147,11 +11148,15 @@ zone_maintenance(dns_zone_t *zone) { * Secondaries send notifies before backing up to disk, * primaries after. */ - if ((zone->type == dns_zone_slave || zone->type == dns_zone_mirror) && - (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || - DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) && - isc_time_compare(&now, &zone->notifytime) >= 0) - { + LOCK_ZONE(zone); + need_notify = (zone->type == dns_zone_slave || + zone->type == dns_zone_mirror) && + (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || + DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) && + (isc_time_compare(&now, &zone->notifytime) >= 0); + UNLOCK_ZONE(zone); + + if (need_notify) { zone_notify(zone, &now); }