Blob Blame History Raw
From 26c4f3e1c9bcba6f61c44af4bfa7c585bfe43f0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= <michal@isc.org>
Date: Mon, 24 Sep 2018 19:33:16 +0200
Subject: [PATCH] Prevent a race after zone load

Zone loading happens in a different task (zone->loadtask) than other
zone actions (zone->task).  Thus, when zone_postload() is called in the
context of zone->loadtask, it may cause zone maintenance to be queued in
zone->task and another thread can then execute zone_maintenance() before
zone_postload() gets a chance to finish its work in the first thread.
This would not be a problem if zone_maintenance() accounted for this
possibility by locking the zone before checking the state of its
DNS_ZONEFLG_LOADPENDING flag.  However, the zone is currently not locked
before the state of that flag is checked, which may prevent zone
maintenance from happening despite zone_postload() scheduling it.  Fix
by locking the zone in zone_maintenance() before checking the state of
the zone's DNS_ZONEFLG_LOADPENDING flag.

(cherry picked from commit 56003e9f9f72c8be67d553f4dbd16eba849ca864)
---
 lib/dns/zone.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index 42a1811..f2ae6f3 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -10005,12 +10005,6 @@ zone_maintenance(dns_zone_t *zone) {
 	REQUIRE(DNS_ZONE_VALID(zone));
 	ENTER;
 
-	/*
-	 * Are we pending load/reload?
-	 */
-	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
-		return;
-
 	/*
 	 * Configuring the view of this zone may have
 	 * failed, for example because the config file
@@ -10019,7 +10013,11 @@ zone_maintenance(dns_zone_t *zone) {
 	 * to do further maintenance on it.
 	 */
 	LOCK_ZONE(zone);
-	viewok = (zone->view != NULL && zone->view->adb != NULL);
+	/*
+	 * Are we pending load/reload?
+	 */
+	viewok = (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) &&
+		  zone->view != NULL && zone->view->adb != NULL);
 	UNLOCK_ZONE(zone);
 	if (!viewok) {
 		return;
-- 
2.31.1