From 384b3ef59677492305713f8f99baf3d0d06e2d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Witold=20Kr=C4=99cicki?= Date: Thu, 25 Oct 2018 18:49:28 +0000 Subject: [PATCH 1/3] Fix a race in RPZ with min-update-interval set to 0 If another RPZ update is pending when processing the previous one nears completion and min-update-interval is set to 0, isc_timer_reset() gets called with 'interval' set to 0, which triggers an assertion failure. To prevent such a scenario from causing a crash, queue the update event directly instead of asking the timer thread to do it. (cherry picked from commit faf2c7711aadde2c9bf7a142e7a53fc26236ebae) --- CHANGES | 6 ++++++ lib/dns/rpz.c | 36 ++++++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index 5e60f69f8e..4ad5c537a0 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,12 @@ 5070. [bug] Record types which support a empty rdata field were not handling the empty rdata field case. [GL #638] +5069. [bug] Fix a hang on in RPZ when named is shutdown during RPZ + zone update. [GL !907] + +5068. [bug] Fix a race in RPZ with min-update-interval set to 0. + [GL #643] + 5066. [cleanup] Allow unquoted strings to be used as a zone names in response-policy statements. [GL #641] diff --git a/lib/dns/rpz.c b/lib/dns/rpz.c index 6b01640267..982f22887b 100644 --- a/lib/dns/rpz.c +++ b/lib/dns/rpz.c @@ -1813,18 +1813,30 @@ finish_update(dns_rpz_zone_t *rpz) { * If there's an update pending schedule it */ if (rpz->updatepending == true) { - uint64_t defer = rpz->min_update_interval; - isc_interval_t interval; - dns_name_format(&rpz->origin, dname, - DNS_NAME_FORMATSIZE); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_INFO, - "rpz: %s: new zone version came " - "too soon, deferring update for " - "%" PRIu64 " seconds", dname, defer); - isc_interval_set(&interval, (unsigned int)defer, 0); - isc_timer_reset(rpz->updatetimer, isc_timertype_once, - NULL, &interval, true); + if (rpz->min_update_interval > 0) { + uint64_t defer = rpz->min_update_interval; + isc_interval_t interval; + dns_name_format(&rpz->origin, dname, + DNS_NAME_FORMATSIZE); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_MASTER, ISC_LOG_INFO, + "rpz: %s: new zone version came " + "too soon, deferring update for " + "%" PRIu64 " seconds", dname, defer); + isc_interval_set(&interval, (unsigned int)defer, 0); + isc_timer_reset(rpz->updatetimer, isc_timertype_once, + NULL, &interval, true); + } else { + isc_event_t *event; + INSIST(!ISC_LINK_LINKED(&rpz->updateevent, ev_link)); + ISC_EVENT_INIT(&rpz->updateevent, + sizeof(rpz->updateevent), 0, NULL, + DNS_EVENT_RPZUPDATED, + dns_rpz_update_taskaction, + rpz, rpz, NULL, NULL); + event = &rpz->updateevent; + isc_task_send(rpz->rpzs->updater, &event); + } } UNLOCK(&rpz->rpzs->maint_lock); From 72585356559d9928b11fec2ab5aaa059821e14a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Mon, 29 Oct 2018 22:29:31 +0100 Subject: [PATCH 2/3] Release all resources when shutting down an RPZ zone during an update If an RPZ zone is to be freed during an update, canceling the update_quantum() event is not enough because the resources released when an update completes also need to be accounted for. Failure to do this results in a hang upon shutdown. Fix by copying cleanup code from the end of update_quantum() to rpz_detach(). (cherry picked from commit 139bc2c6abdadc584fb53becdb0a7885160afc0d) --- lib/dns/rpz.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/dns/rpz.c b/lib/dns/rpz.c index 982f22887b..324ab5fc57 100644 --- a/lib/dns/rpz.c +++ b/lib/dns/rpz.c @@ -2125,6 +2125,14 @@ rpz_detach(dns_rpz_zone_t **rpzp, dns_rpz_zones_t *rpzs) { } if (rpz->updaterunning) { isc_task_purgeevent(rpz->rpzs->updater, &rpz->updateevent); + if (rpz->updbit != NULL) { + dns_dbiterator_destroy(&rpz->updbit); + } + if (rpz->newnodes != NULL) { + isc_ht_destroy(&rpz->newnodes); + } + dns_db_closeversion(rpz->updb, &rpz->updbversion, false); + dns_db_detach(&rpz->updb); } isc_timer_reset(rpz->updatetimer, isc_timertype_inactive, From c209bb14002eb5c0d745d945225a1ee6ac9b86cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Witold=20Kr=C4=99cicki?= Date: Mon, 29 Oct 2018 23:03:51 +0100 Subject: [PATCH 3/3] include in rpz.c for strtoul (cherry picked from commit 8283cbabdc0fad1ac12e2c207a9e202353067dcb) --- lib/dns/rpz.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/dns/rpz.c b/lib/dns/rpz.c index 324ab5fc57..266b908c29 100644 --- a/lib/dns/rpz.c +++ b/lib/dns/rpz.c @@ -15,6 +15,7 @@ #include #include +#include #include #include