|
|
34afcc |
From 26c4f3e1c9bcba6f61c44af4bfa7c585bfe43f0b Mon Sep 17 00:00:00 2001
|
|
|
34afcc |
From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= <michal@isc.org>
|
|
|
34afcc |
Date: Mon, 24 Sep 2018 19:33:16 +0200
|
|
|
34afcc |
Subject: [PATCH] Prevent a race after zone load
|
|
|
34afcc |
|
|
|
34afcc |
Zone loading happens in a different task (zone->loadtask) than other
|
|
|
34afcc |
zone actions (zone->task). Thus, when zone_postload() is called in the
|
|
|
34afcc |
context of zone->loadtask, it may cause zone maintenance to be queued in
|
|
|
34afcc |
zone->task and another thread can then execute zone_maintenance() before
|
|
|
34afcc |
zone_postload() gets a chance to finish its work in the first thread.
|
|
|
34afcc |
This would not be a problem if zone_maintenance() accounted for this
|
|
|
34afcc |
possibility by locking the zone before checking the state of its
|
|
|
34afcc |
DNS_ZONEFLG_LOADPENDING flag. However, the zone is currently not locked
|
|
|
34afcc |
before the state of that flag is checked, which may prevent zone
|
|
|
34afcc |
maintenance from happening despite zone_postload() scheduling it. Fix
|
|
|
34afcc |
by locking the zone in zone_maintenance() before checking the state of
|
|
|
34afcc |
the zone's DNS_ZONEFLG_LOADPENDING flag.
|
|
|
34afcc |
|
|
|
34afcc |
(cherry picked from commit 56003e9f9f72c8be67d553f4dbd16eba849ca864)
|
|
|
34afcc |
---
|
|
|
34afcc |
lib/dns/zone.c | 12 +++++-------
|
|
|
34afcc |
1 file changed, 5 insertions(+), 7 deletions(-)
|
|
|
34afcc |
|
|
|
34afcc |
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
|
|
|
34afcc |
index 42a1811..f2ae6f3 100644
|
|
|
34afcc |
--- a/lib/dns/zone.c
|
|
|
34afcc |
+++ b/lib/dns/zone.c
|
|
|
34afcc |
@@ -10005,12 +10005,6 @@ zone_maintenance(dns_zone_t *zone) {
|
|
|
34afcc |
REQUIRE(DNS_ZONE_VALID(zone));
|
|
|
34afcc |
ENTER;
|
|
|
34afcc |
|
|
|
34afcc |
- /*
|
|
|
34afcc |
- * Are we pending load/reload?
|
|
|
34afcc |
- */
|
|
|
34afcc |
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
|
|
|
34afcc |
- return;
|
|
|
34afcc |
-
|
|
|
34afcc |
/*
|
|
|
34afcc |
* Configuring the view of this zone may have
|
|
|
34afcc |
* failed, for example because the config file
|
|
|
34afcc |
@@ -10019,7 +10013,11 @@ zone_maintenance(dns_zone_t *zone) {
|
|
|
34afcc |
* to do further maintenance on it.
|
|
|
34afcc |
*/
|
|
|
34afcc |
LOCK_ZONE(zone);
|
|
|
34afcc |
- viewok = (zone->view != NULL && zone->view->adb != NULL);
|
|
|
34afcc |
+ /*
|
|
|
34afcc |
+ * Are we pending load/reload?
|
|
|
34afcc |
+ */
|
|
|
34afcc |
+ viewok = (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) &&
|
|
|
34afcc |
+ zone->view != NULL && zone->view->adb != NULL);
|
|
|
34afcc |
UNLOCK_ZONE(zone);
|
|
|
34afcc |
if (!viewok) {
|
|
|
34afcc |
return;
|
|
|
34afcc |
--
|
|
|
34afcc |
2.31.1
|
|
|
34afcc |
|