]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Resolve TSAN data race in zone_maintenance
authorDiego Fronza <diego@isc.org>
Wed, 7 Apr 2021 13:48:12 +0000 (10:48 -0300)
committerDiego Fronza <diego@isc.org>
Wed, 7 Apr 2021 13:48:12 +0000 (10:48 -0300)
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 a895b254342180f38c4f5c3d24735785854b4685..9866f8518422e71cf72bbc28d5612ebb8a6b803a 100644 (file)
@@ -10187,6 +10187,7 @@ zone_maintenance(dns_zone_t *zone) {
        isc_time_t now;
        isc_result_t result;
        bool dumping, load_pending, viewok, start_refresh;
+       bool need_notify;
 
        REQUIRE(DNS_ZONE_VALID(zone));
        ENTER;
@@ -10268,11 +10269,16 @@ zone_maintenance(dns_zone_t *zone) {
        /*
         * Slaves send notifies before backing up to disk, masters after.
         */
-       if (zone->type == dns_zone_slave &&
-           (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 &&
+                     (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);
+       }
 
        /*
         * Do we need to consolidate the backing store?