]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Resolve TSAN data race in zone_maintenance
authorDiego Fronza <diego@isc.org>
Tue, 6 Apr 2021 19:29:25 +0000 (16:29 -0300)
committerDiego dos Santos Fronza <diego@isc.org>
Wed, 7 Apr 2021 12:04:01 +0000 (12:04 +0000)
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

index 4f98f38a6a8b1ed76e11a16a2aa0d527e2ccdf3d..c9bca4bd94179037feb4bd7e6a0096cd1dfef33d 100644 (file)
@@ -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);
        }