From cc1d4e1aa63fdc7e82a00fd7b06d50fb4dbc8e96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Thu, 30 Dec 2021 15:14:11 +0100 Subject: [PATCH] Ensure the correct ordering zone_shutdown() vs zone_gotwritehandle() When the signed version of an inline-signed zone is dumped to disk, the serial number of the unsigned version of the zone is written in the raw-format header so that the contents of the signed zone can be resynchronized after named restart if the unsigned zone file is modified while named is not running (see RT #26676). In order for the serial number of the unsigned zone to be determined during the dump, zone->raw must be set to a non-NULL value. This should always be the case as long as the signed version of the zone is used for anything by named. However, under certain circumstances the zone->raw could be set to NULL while the zone is being dumped. Defer detaching from zone->raw in zone_shutdown() if the zone is in the process of being dumped to disk. --- lib/dns/zone.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 2e54038b3c..2241f99089 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -11947,6 +11947,9 @@ dump_done(void *arg, isc_result_t result) { dns_dumpctx_detach(&zone->dctx); } zonemgr_putio(&zone->writeio); + if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && zone->raw != NULL) { + dns_zone_detach(&zone->raw); + } UNLOCK_ZONE(zone); if (again) { (void)zone_dump(zone, false); @@ -15028,7 +15031,7 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) { */ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN); free_needed = exit_check(zone); - if (inline_secure(zone)) { + if (inline_secure(zone) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { raw = zone->raw; zone->raw = NULL; }