From 0127ba6472a210f7ca41bf18e5a5c9b015f20c6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Mon, 19 Apr 2021 09:25:14 +0200 Subject: [PATCH] Fix task timing race in setnsec3param() When setnsec3param() is schedule from zone_postload() there's no guarantee that `zone->db` is not `NULL` yet. Thus when the setnsec3param() is called, we need to check for `zone->db` existence and reschedule the task, because calling `rss_post()` on a zone with empty `.db` ends up with no-op (the function just returns). --- lib/dns/zone.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index e0a94a6d00..adfe082a4b 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -21119,6 +21119,22 @@ setnsec3param(isc_task_t *task, isc_event_t *event) { */ ISC_LIST_APPEND(zone->rss_post, event, ev_link); } else { + bool rescheduled = false; + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + /* + * The zone is not yet fully loaded. Reschedule the event to + * be picked up later. This turns this function into a busy + * wait, but it only happens at startup. + */ + if (zone->db == NULL) { + rescheduled = true; + isc_task_send(task, &event); + } + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + if (rescheduled) { + return; + } + rss_post(zone, event); } dns_zone_idetach(&zone);