From 26c4f3e1c9bcba6f61c44af4bfa7c585bfe43f0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= 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